diff --git a/CHANGELOG.md b/CHANGELOG.md index c8c1251bd..66ba9ac6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This project follows [Semantic Versioning](http://semver.org) guidelines. ### Added * Added a new client API endpoint for gathering the utilization stats for servers including disk, cpu, and memory. `GET /api/client/servers//utilization` +* Added validation to variable validation rules to validate that the validation rules are valid because we heard you like validating your validation. ## v0.7.6 (Derelict Dermodactylus) ### Fixed diff --git a/app/Exceptions/Service/Egg/Variable/BadValidationRuleException.php b/app/Exceptions/Service/Egg/Variable/BadValidationRuleException.php new file mode 100644 index 000000000..9e7ca3b43 --- /dev/null +++ b/app/Exceptions/Service/Egg/Variable/BadValidationRuleException.php @@ -0,0 +1,9 @@ +repository = $repository; + $this->validator = $validator; + } + + /** + * Return the validation factory instance to be used by rule validation + * checking in the trait. + * + * @return \Illuminate\Contracts\Validation\Factory + */ + protected function getValidator(): Factory + { + return $this->validator; } /** @@ -31,6 +53,7 @@ class VariableCreationService * @return \Pterodactyl\Models\EggVariable * * @throws \Pterodactyl\Exceptions\Model\DataValidationException + * @throws \Pterodactyl\Exceptions\Service\Egg\Variable\BadValidationRuleException * @throws \Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException */ public function handle(int $egg, array $data): EggVariable @@ -42,6 +65,10 @@ class VariableCreationService )); } + if (! empty($data['rules'] ?? '')) { + $this->validateRules($data['rules']); + } + $options = array_get($data, 'options') ?? []; return $this->repository->create([ diff --git a/app/Services/Eggs/Variables/VariableUpdateService.php b/app/Services/Eggs/Variables/VariableUpdateService.php index 9960e78c9..15bbe2d31 100644 --- a/app/Services/Eggs/Variables/VariableUpdateService.php +++ b/app/Services/Eggs/Variables/VariableUpdateService.php @@ -3,25 +3,47 @@ namespace Pterodactyl\Services\Eggs\Variables; use Pterodactyl\Models\EggVariable; +use Illuminate\Contracts\Validation\Factory; use Pterodactyl\Exceptions\DisplayException; +use Pterodactyl\Traits\Services\ValidatesValidationRules; use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface; use Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException; class VariableUpdateService { + use ValidatesValidationRules; + /** * @var \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface */ - protected $repository; + private $repository; + + /** + * @var \Illuminate\Contracts\Validation\Factory + */ + private $validator; /** * VariableUpdateService constructor. * * @param \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface $repository + * @param \Illuminate\Contracts\Validation\Factory $validator */ - public function __construct(EggVariableRepositoryInterface $repository) + public function __construct(EggVariableRepositoryInterface $repository, Factory $validator) { $this->repository = $repository; + $this->validator = $validator; + } + + /** + * Return the validation factory instance to be used by rule validation + * checking in the trait. + * + * @return \Illuminate\Contracts\Validation\Factory + */ + protected function getValidator(): Factory + { + return $this->validator; } /** @@ -58,6 +80,10 @@ class VariableUpdateService } } + if (! empty($data['rules'] ?? '')) { + $this->validateRules($data['rules']); + } + $options = array_get($data, 'options') ?? []; return $this->repository->withoutFreshModel()->update($variable->id, [ diff --git a/app/Traits/Services/ValidatesValidationRules.php b/app/Traits/Services/ValidatesValidationRules.php new file mode 100644 index 000000000..d2010c828 --- /dev/null +++ b/app/Traits/Services/ValidatesValidationRules.php @@ -0,0 +1,40 @@ +getValidator()->make(['__TEST' => 'test'], ['__TEST' => $rules])->fails(); + } catch (BadMethodCallException $exception) { + $matches = []; + if (preg_match('/Method \[(.+)\] does not exist\./', $exception->getMessage(), $matches)) { + throw new BadValidationRuleException(trans('exceptions.nest.variables.bad_validation_rule', [ + 'rule' => Str::snake(str_replace('validate', '', array_get($matches, 1, 'unknownRule'))), + ]), $exception); + } + + throw $exception; + } + } +} diff --git a/resources/lang/en/exceptions.php b/resources/lang/en/exceptions.php index 96395baed..f1d58c6c6 100644 --- a/resources/lang/en/exceptions.php +++ b/resources/lang/en/exceptions.php @@ -24,6 +24,7 @@ return [ 'variables' => [ 'env_not_unique' => 'The environment variable :name must be unique to this Egg.', 'reserved_name' => 'The environment variable :name is protected and cannot be assigned to a variable.', + 'bad_validation_rule' => 'The validation rule ":rule" is not a valid rule for this application.', ], 'importer' => [ 'json_error' => 'There was an error while attempting to parse the JSON file: :error.', diff --git a/resources/themes/pterodactyl/admin/eggs/variables.blade.php b/resources/themes/pterodactyl/admin/eggs/variables.blade.php index 40ee82c8b..baf72f530 100644 --- a/resources/themes/pterodactyl/admin/eggs/variables.blade.php +++ b/resources/themes/pterodactyl/admin/eggs/variables.blade.php @@ -105,20 +105,20 @@