diff --git a/CHANGELOG.md b/CHANGELOG.md index f070441be..dbf875146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ This file is a running track of new features and fixes to each version of the pa This project follows [Semantic Versioning](http://semver.org) guidelines. +## v1.4.0 +### Fixed +* Removes the use of tagging when storing server resource usage in the cache. This addresses errors encountered when using the `file` driver. +* Fixes Wings response handling if Wings returns an error response with a 200-level status code that would improperly be passed back to the client as a successful request. +* Fixes use of JSON specific functions in SQL queries to better support MariaDB users. +* Fixes a migration that could fail on some MySQL/MariaDB setups when trying to encrypt node token values. + +### Changed +* Increases the maximum length allowed for a server name using the Rust egg. +* Updated server resource utilization API call to Wings to use new API response format used by `Wings@1.4.0`. + ## v1.3.2 ### Fixed * Fixes self-upgrade incorrectly executing the command to un-tar downloaded archives. diff --git a/app/Http/Controllers/Api/Client/Servers/ScheduleController.php b/app/Http/Controllers/Api/Client/Servers/ScheduleController.php index 320133595..5b2609e58 100644 --- a/app/Http/Controllers/Api/Client/Servers/ScheduleController.php +++ b/app/Http/Controllers/Api/Client/Servers/ScheduleController.php @@ -156,10 +156,6 @@ class ScheduleController extends ClientApiController */ public function execute(TriggerScheduleRequest $request, Server $server, Schedule $schedule) { - if (!$schedule->is_active) { - throw new BadRequestHttpException('Cannot trigger schedule exection for a schedule that is not currently active.'); - } - $this->service->handle($schedule, true); return new JsonResponse([], JsonResponse::HTTP_ACCEPTED); diff --git a/app/Jobs/Schedule/RunTaskJob.php b/app/Jobs/Schedule/RunTaskJob.php index 3dd8e920d..f60711f43 100644 --- a/app/Jobs/Schedule/RunTaskJob.php +++ b/app/Jobs/Schedule/RunTaskJob.php @@ -27,13 +27,19 @@ class RunTaskJob extends Job implements ShouldQueue */ public $task; + /** + * @var bool + */ + public $manualRun; + /** * RunTaskJob constructor. */ - public function __construct(Task $task) + public function __construct(Task $task, $manualRun = false) { $this->queue = config('pterodactyl.queues.standard'); $this->task = $task; + $this->manualRun = $manualRun; } /** @@ -46,8 +52,8 @@ class RunTaskJob extends Job implements ShouldQueue InitiateBackupService $backupService, DaemonPowerRepository $powerRepository ) { - // Do not process a task that is not set to active. - if (!$this->task->schedule->is_active) { + // Do not process a task that is not set to active, unless it's been manually triggered. + if (!$this->task->schedule->is_active && !$this->manualRun) { $this->markTaskNotQueued(); $this->markScheduleComplete(); @@ -101,7 +107,7 @@ class RunTaskJob extends Job implements ShouldQueue $nextTask->update(['is_queued' => true]); - $this->dispatch((new self($nextTask))->delay($nextTask->time_offset)); + $this->dispatch((new self($nextTask, $this->manualRun))->delay($nextTask->time_offset)); } /** diff --git a/app/Services/Schedules/ProcessScheduleService.php b/app/Services/Schedules/ProcessScheduleService.php index 23c9ea5e8..9e62d45cb 100644 --- a/app/Services/Schedules/ProcessScheduleService.php +++ b/app/Services/Schedules/ProcessScheduleService.php @@ -53,7 +53,7 @@ class ProcessScheduleService $task->update(['is_queued' => true]); }); - $job = new RunTaskJob($task); + $job = new RunTaskJob($task, $now); if (!$now) { $this->dispatcher->dispatch($job->delay($task->time_offset)); diff --git a/app/Traits/Commands/EnvironmentWriterTrait.php b/app/Traits/Commands/EnvironmentWriterTrait.php index 10692a9a4..5435dc321 100644 --- a/app/Traits/Commands/EnvironmentWriterTrait.php +++ b/app/Traits/Commands/EnvironmentWriterTrait.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Traits\Commands; @@ -13,6 +6,20 @@ use Pterodactyl\Exceptions\PterodactylException; trait EnvironmentWriterTrait { + /** + * Escapes an environment value by looking for any characters that could + * reasonablly cause environment parsing issues. Those values are then wrapped + * in quotes before being returned. + */ + public function escapeEnvironmentValue(string $value): string + { + if (!preg_match('/^\"(.*)\"$/', $value) && preg_match('/([^\w.\-+\/])+/', $value)) { + return sprintf('"%s"', addslashes($value)); + } + + return $value; + } + /** * Update the .env file for the application using the passed in values. * @@ -28,14 +35,7 @@ trait EnvironmentWriterTrait $saveContents = file_get_contents($path); collect($values)->each(function ($value, $key) use (&$saveContents) { $key = strtoupper($key); - // If the key value is not sorrounded by quotation marks, and contains anything that could reasonably - // cause environment parsing issues, wrap it in quotes before writing it. This also adds slashes to the - // value to ensure quotes within it don't cause us issues. - if (!preg_match('/^\"(.*)\"$/', $value) && preg_match('/([^\w.\-+\/])+/', $value)) { - $value = sprintf('"%s"', addslashes($value)); - } - - $saveValue = sprintf('%s=%s', $key, $value); + $saveValue = sprintf('%s=%s', $key, $this->escapeEnvironmentValue($value)); if (preg_match_all('/^' . $key . '=(.*)$/m', $saveContents) < 1) { $saveContents = $saveContents . PHP_EOL . $saveValue; diff --git a/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx b/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx index df0af5b99..60d7ca943 100644 --- a/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx +++ b/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx @@ -161,7 +161,7 @@ export default () => { onDeleted={() => history.push(`/server/${id}/schedules`)} /> - {schedule.isActive && schedule.tasks.length > 0 && + {schedule.tasks.length > 0 && diff --git a/tests/Integration/Api/Client/Server/Schedule/ExecuteScheduleTest.php b/tests/Integration/Api/Client/Server/Schedule/ExecuteScheduleTest.php index 7c9d34d18..9964691aa 100644 --- a/tests/Integration/Api/Client/Server/Schedule/ExecuteScheduleTest.php +++ b/tests/Integration/Api/Client/Server/Schedule/ExecuteScheduleTest.php @@ -51,26 +51,6 @@ class ExecuteScheduleTest extends ClientApiIntegrationTestCase }); } - /** - * Test that the schedule is not executed if it is not currently active. - */ - public function testScheduleIsNotExecutedIfNotActive() - { - [$user, $server] = $this->generateTestAccount(); - - /** @var \Pterodactyl\Models\Schedule $schedule */ - $schedule = Schedule::factory()->create([ - 'server_id' => $server->id, - 'is_active' => false, - ]); - - $response = $this->actingAs($user)->postJson($this->link($schedule, '/execute')); - - $response->assertStatus(Response::HTTP_BAD_REQUEST); - $response->assertJsonPath('errors.0.code', 'BadRequestHttpException'); - $response->assertJsonPath('errors.0.detail', 'Cannot trigger schedule exection for a schedule that is not currently active.'); - } - /** * Test that a user without the schedule update permission cannot execute it. */ diff --git a/tests/Unit/Helpers/EnvironmentWriterTraitTest.php b/tests/Unit/Helpers/EnvironmentWriterTraitTest.php new file mode 100644 index 000000000..f2022f798 --- /dev/null +++ b/tests/Unit/Helpers/EnvironmentWriterTraitTest.php @@ -0,0 +1,43 @@ +escapeEnvironmentValue($input); + + $this->assertSame($expected, $output); + } + + public function variableDataProvider(): array + { + return [ + ['foo', 'foo'], + ['abc123', 'abc123'], + ['val"ue', '"val\"ue"'], + ['my test value', '"my test value"'], + ['mysql_p@assword', '"mysql_p@assword"'], + ['mysql_p#assword', '"mysql_p#assword"'], + ['mysql p@$$word', '"mysql p@$$word"'], + ['mysql p%word', '"mysql p%word"'], + ['mysql p#word', '"mysql p#word"'], + ['abc_@#test', '"abc_@#test"'], + ['test 123 $$$', '"test 123 $$$"'], + ['#password%', '"#password%"'], + ['$pass ', '"$pass "'], + ]; + } +} + +class FooClass +{ + use EnvironmentWriterTrait; +}