Merge branch 'develop' into matthewpi/security-keys-backport
This commit is contained in:
commit
f631ac1946
1153 changed files with 25099 additions and 37002 deletions
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
abstract class AdminFormRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* The rules to apply to the incoming form request.
|
||||
*/
|
||||
abstract public function rules(): array;
|
||||
|
||||
/**
|
||||
* Determine if the user is an admin and has permission to access this
|
||||
* form controller in the first place.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
if (is_null($this->user())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) $this->user()->root_admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only the fields that we are interested in from the request.
|
||||
* This will include empty fields as a null value.
|
||||
*/
|
||||
public function normalize(array $only = null): array
|
||||
{
|
||||
return $this->only($only ?? array_keys($this->rules()));
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Api;
|
||||
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class StoreApplicationApiKeyRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* @throws \ReflectionException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$modelRules = ApiKey::getRules();
|
||||
|
||||
return collect(AdminAcl::getResourceList())->mapWithKeys(function ($resource) use ($modelRules) {
|
||||
return [AdminAcl::COLUMN_IDENTIFIER . $resource => $modelRules['r_' . $resource]];
|
||||
})->merge(['memo' => $modelRules['memo']])->toArray();
|
||||
}
|
||||
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'memo' => 'Description',
|
||||
];
|
||||
}
|
||||
|
||||
public function getKeyPermissions(): array
|
||||
{
|
||||
return collect($this->validated())->filter(function ($value, $key) {
|
||||
return substr($key, 0, strlen(AdminAcl::COLUMN_IDENTIFIER)) === AdminAcl::COLUMN_IDENTIFIER;
|
||||
})->toArray();
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin;
|
||||
|
||||
class BaseFormRequest extends AdminFormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'company' => 'required|between:1,256',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin;
|
||||
|
||||
use Pterodactyl\Models\DatabaseHost;
|
||||
use Illuminate\Contracts\Validation\Validator;
|
||||
|
||||
class DatabaseHostFormRequest extends AdminFormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
if ($this->method() !== 'POST') {
|
||||
return DatabaseHost::getRulesForUpdate($this->route()->parameter('host'));
|
||||
}
|
||||
|
||||
return DatabaseHost::getRules();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify submitted data before it is passed off to the validator.
|
||||
*/
|
||||
protected function getValidatorInstance(): Validator
|
||||
{
|
||||
if (!$this->filled('node_id')) {
|
||||
$this->merge(['node_id' => null]);
|
||||
}
|
||||
|
||||
return parent::getValidatorInstance();
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Egg;
|
||||
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class EggFormRequest extends AdminFormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|string|max:191',
|
||||
'description' => 'nullable|string',
|
||||
'docker_images' => 'required|string',
|
||||
'force_outgoing_ip' => 'sometimes|boolean',
|
||||
'file_denylist' => 'array',
|
||||
'startup' => 'required|string',
|
||||
'config_from' => 'sometimes|bail|nullable|numeric',
|
||||
'config_stop' => 'required_without:config_from|nullable|string|max:191',
|
||||
'config_startup' => 'required_without:config_from|nullable|json',
|
||||
'config_logs' => 'required_without:config_from|nullable|json',
|
||||
'config_files' => 'required_without:config_from|nullable|json',
|
||||
];
|
||||
|
||||
if ($this->method() === 'POST') {
|
||||
$rules['nest_id'] = 'required|numeric|exists:nests,id';
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function withValidator($validator)
|
||||
{
|
||||
$validator->sometimes('config_from', 'exists:eggs,id', function () {
|
||||
return (int) $this->input('config_from') !== 0;
|
||||
});
|
||||
}
|
||||
|
||||
public function validated($key = null, $default = null): array
|
||||
{
|
||||
$data = parent::validated();
|
||||
|
||||
return array_merge($data, [
|
||||
'force_outgoing_ip' => array_get($data, 'force_outgoing_ip', false),
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Egg;
|
||||
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class EggImportFormRequest extends AdminFormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'import_file' => 'bail|required|file|max:1000|mimetypes:application/json,text/plain',
|
||||
];
|
||||
|
||||
if ($this->method() !== 'PUT') {
|
||||
$rules['import_to_nest'] = 'bail|required|integer|exists:nests,id';
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Egg;
|
||||
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class EggScriptFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Return the rules to be used when validating the data sent in the request.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'script_install' => 'sometimes|nullable|string',
|
||||
'script_is_privileged' => 'sometimes|required|boolean',
|
||||
'script_entry' => 'sometimes|required|string',
|
||||
'script_container' => 'sometimes|required|string',
|
||||
'copy_script_from' => 'sometimes|nullable|numeric',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Egg;
|
||||
|
||||
use Pterodactyl\Models\EggVariable;
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class EggVariableFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Define rules for validation of this request.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|min:1|max:191',
|
||||
'description' => 'sometimes|nullable|string',
|
||||
'env_variable' => 'required|regex:/^[\w]{1,191}$/|notIn:' . EggVariable::RESERVED_ENV_NAMES,
|
||||
'options' => 'sometimes|required|array',
|
||||
'rules' => 'bail|required|string',
|
||||
'default_value' => 'present',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin;
|
||||
|
||||
use Pterodactyl\Models\Location;
|
||||
|
||||
class LocationFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Set up the validation rules to use for these requests.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
if ($this->method() === 'PATCH') {
|
||||
return Location::getRulesForUpdate($this->route()->parameter('location')->id);
|
||||
}
|
||||
|
||||
return Location::getRules();
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin;
|
||||
|
||||
use Pterodactyl\Models\Mount;
|
||||
|
||||
class MountFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Set up the validation rules to use for these requests.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
if ($this->method() === 'PATCH') {
|
||||
return Mount::getRulesForUpdate($this->route()->parameter('mount')->id);
|
||||
}
|
||||
|
||||
return Mount::getRules();
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Nest;
|
||||
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class StoreNestFormRequest extends AdminFormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|min:1|max:191',
|
||||
'description' => 'string|nullable',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin;
|
||||
|
||||
use Pterodactyl\Models\User;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class NewUserFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Rules to apply to requests for updating or creating a user
|
||||
* in the Admin CP.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return Collection::make(
|
||||
User::getRules()
|
||||
)->only([
|
||||
'email',
|
||||
'username',
|
||||
'name_first',
|
||||
'name_last',
|
||||
'password',
|
||||
'language',
|
||||
'root_admin',
|
||||
])->toArray();
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Node;
|
||||
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class AllocationAliasFormRequest extends AdminFormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'alias' => 'present|nullable|string',
|
||||
'allocation_id' => 'required|numeric|exists:allocations,id',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Node;
|
||||
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class AllocationFormRequest extends AdminFormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'allocation_ip' => 'required|string',
|
||||
'allocation_alias' => 'sometimes|nullable|string|max:191',
|
||||
'allocation_ports' => 'required|array',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Node;
|
||||
|
||||
use Pterodactyl\Rules\Fqdn;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class NodeFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Get rules to apply to data in this request.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
if ($this->method() === 'PATCH') {
|
||||
return Node::getRulesForUpdate($this->route()->parameter('node'));
|
||||
}
|
||||
|
||||
$data = Node::getRules();
|
||||
$data['fqdn'][] = Fqdn::make('scheme');
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin;
|
||||
|
||||
use Pterodactyl\Models\Server;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
class ServerFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Rules to be applied to this request.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = Server::getRules();
|
||||
$rules['description'][] = 'nullable';
|
||||
$rules['custom_image'] = 'sometimes|nullable|string';
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run validation after the rules above have been applied.
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(function ($validator) {
|
||||
$validator->sometimes('node_id', 'required|numeric|bail|exists:nodes,id', function ($input) {
|
||||
return !$input->auto_deploy;
|
||||
});
|
||||
|
||||
$validator->sometimes('allocation_id', [
|
||||
'required',
|
||||
'numeric',
|
||||
'bail',
|
||||
Rule::exists('allocations', 'id')->where(function ($query) {
|
||||
$query->where('node_id', $this->input('node_id'));
|
||||
$query->whereNull('server_id');
|
||||
}),
|
||||
], function ($input) {
|
||||
return !$input->auto_deploy;
|
||||
});
|
||||
|
||||
$validator->sometimes('allocation_additional.*', [
|
||||
'sometimes',
|
||||
'required',
|
||||
'numeric',
|
||||
Rule::exists('allocations', 'id')->where(function ($query) {
|
||||
$query->where('node_id', $this->input('node_id'));
|
||||
$query->whereNull('server_id');
|
||||
}),
|
||||
], function ($input) {
|
||||
return !$input->auto_deploy;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Servers\Databases;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class StoreServerDatabaseRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Validation rules for database creation.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'database' => [
|
||||
'required',
|
||||
'string',
|
||||
'min:1',
|
||||
'max:24',
|
||||
Rule::unique('databases')->where(function (Builder $query) {
|
||||
$query->where('database_host_id', $this->input('database_host_id') ?? 0);
|
||||
}),
|
||||
],
|
||||
'max_connections' => 'nullable',
|
||||
'remote' => 'required|string|regex:/^[0-9%.]{1,15}$/',
|
||||
'database_host_id' => 'required|integer|exists:database_hosts,id',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Settings;
|
||||
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class AdvancedSettingsFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Return all the rules to apply to this request's data.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'recaptcha:enabled' => 'required|in:true,false',
|
||||
'recaptcha:secret_key' => 'required|string|max:191',
|
||||
'recaptcha:website_key' => 'required|string|max:191',
|
||||
'pterodactyl:guzzle:timeout' => 'required|integer|between:1,60',
|
||||
'pterodactyl:guzzle:connect_timeout' => 'required|integer|between:1,60',
|
||||
'pterodactyl:client_features:allocations:enabled' => 'required|in:true,false',
|
||||
'pterodactyl:client_features:allocations:range_start' => [
|
||||
'nullable',
|
||||
'required_if:pterodactyl:client_features:allocations:enabled,true',
|
||||
'integer',
|
||||
'between:1024,65535',
|
||||
],
|
||||
'pterodactyl:client_features:allocations:range_end' => [
|
||||
'nullable',
|
||||
'required_if:pterodactyl:client_features:allocations:enabled,true',
|
||||
'integer',
|
||||
'between:1024,65535',
|
||||
'gt:pterodactyl:client_features:allocations:range_start',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'recaptcha:enabled' => 'reCAPTCHA Enabled',
|
||||
'recaptcha:secret_key' => 'reCAPTCHA Secret Key',
|
||||
'recaptcha:website_key' => 'reCAPTCHA Website Key',
|
||||
'pterodactyl:guzzle:timeout' => 'HTTP Request Timeout',
|
||||
'pterodactyl:guzzle:connect_timeout' => 'HTTP Connection Timeout',
|
||||
'pterodactyl:client_features:allocations:enabled' => 'Auto Create Allocations Enabled',
|
||||
'pterodactyl:client_features:allocations:range_start' => 'Starting Port',
|
||||
'pterodactyl:client_features:allocations:range_end' => 'Ending Port',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Settings;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Pterodactyl\Traits\Helpers\AvailableLanguages;
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class BaseSettingsFormRequest extends AdminFormRequest
|
||||
{
|
||||
use AvailableLanguages;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'app:name' => 'required|string|max:191',
|
||||
'pterodactyl:auth:2fa_required' => 'required|integer|in:0,1,2',
|
||||
'app:locale' => ['required', 'string', Rule::in(array_keys($this->getAvailableLanguages()))],
|
||||
];
|
||||
}
|
||||
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'app:name' => 'Company Name',
|
||||
'pterodactyl:auth:2fa_required' => 'Require 2-Factor Authentication',
|
||||
'app:locale' => 'Default Language',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Settings;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class MailSettingsFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Return rules to validate mail settings POST data against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'mail:host' => 'required|string',
|
||||
'mail:port' => 'required|integer|between:1,65535',
|
||||
'mail:encryption' => ['present', Rule::in([null, 'tls', 'ssl'])],
|
||||
'mail:username' => 'nullable|string|max:191',
|
||||
'mail:password' => 'nullable|string|max:191',
|
||||
'mail:from:address' => 'required|string|email',
|
||||
'mail:from:name' => 'nullable|string|max:191',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the default normalization function for this type of request
|
||||
* as we need to accept empty values on the keys.
|
||||
*/
|
||||
public function normalize(array $only = null): array
|
||||
{
|
||||
$keys = array_flip(array_keys($this->rules()));
|
||||
|
||||
if (empty($this->input('mail:password'))) {
|
||||
unset($keys['mail:password']);
|
||||
}
|
||||
|
||||
return $this->only(array_flip($keys));
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin;
|
||||
|
||||
use Pterodactyl\Models\User;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class UserFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* Rules to apply to requests for updating or creating a user
|
||||
* in the Admin CP.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return Collection::make(
|
||||
User::getRulesForUpdate($this->route()->parameter('user'))
|
||||
)->only([
|
||||
'email',
|
||||
'username',
|
||||
'name_first',
|
||||
'name_last',
|
||||
'password',
|
||||
'language',
|
||||
'root_admin',
|
||||
])->toArray();
|
||||
}
|
||||
}
|
83
app/Http/Requests/Api/ApiRequest.php
Normal file
83
app/Http/Requests/Api/ApiRequest.php
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* @method \Pterodactyl\Models\User user($guard = null)
|
||||
*/
|
||||
abstract class ApiRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Tracks if the request has been validated internally or not to avoid
|
||||
* making duplicate validation calls.
|
||||
*/
|
||||
private bool $hasValidated = false;
|
||||
|
||||
/**
|
||||
* Determine if the current user is authorized to perform the requested
|
||||
* action against the API.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default set of rules to apply to API requests.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the resource exists and can be accessed prior to booting
|
||||
* the validator and attempting to use the data.
|
||||
*
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
if (!$this->passesAuthorization()) {
|
||||
$this->failedAuthorization();
|
||||
}
|
||||
|
||||
$this->hasValidated = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if the request passes the authorization check as well
|
||||
* as the exists check.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
*/
|
||||
protected function passesAuthorization()
|
||||
{
|
||||
// If we have already validated we do not need to call this function
|
||||
// again. This is needed to work around Laravel's normal auth validation
|
||||
// that occurs after validating the request params since we are doing auth
|
||||
// validation in the prepareForValidation() function.
|
||||
if ($this->hasValidated) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!parent::passesAuthorization()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only let the user know that a resource does not exist if they are
|
||||
// authenticated to access the endpoint. This avoids exposing that
|
||||
// an item exists (or does not exist) to the user until they can prove
|
||||
// that they have permission to know about it.
|
||||
if ($this->attributes->get('is_missing_model', false)) {
|
||||
throw new NotFoundHttpException(trans('exceptions.api.resource_not_found'));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Allocations;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class DeleteAllocationRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_ALLOCATIONS;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Allocations;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetAllocationsRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_ALLOCATIONS;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
||||
|
|
|
@ -2,15 +2,11 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Allocations;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Illuminate\Support\Arr;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreAllocationRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_ALLOCATIONS;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
|
@ -21,14 +17,22 @@ class StoreAllocationRequest extends ApplicationApiRequest
|
|||
];
|
||||
}
|
||||
|
||||
public function validated($key = null, $default = null): array
|
||||
/**
|
||||
* @param string|null $key
|
||||
* @param string|array|null $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function validated($key = null, $default = null)
|
||||
{
|
||||
$data = parent::validated();
|
||||
|
||||
return [
|
||||
$response = [
|
||||
'allocation_ip' => $data['ip'],
|
||||
'allocation_ports' => $data['ports'],
|
||||
'allocation_alias' => $data['alias'] ?? null,
|
||||
];
|
||||
|
||||
return is_null($key) ? $response : Arr::get($response, $key, $default);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,92 +2,16 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application;
|
||||
|
||||
use Webmozart\Assert\Assert;
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Laravel\Sanctum\TransientToken;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Pterodactyl\Exceptions\PterodactylException;
|
||||
use Pterodactyl\Http\Requests\Api\ApiRequest;
|
||||
|
||||
abstract class ApplicationApiRequest extends FormRequest
|
||||
abstract class ApplicationApiRequest extends ApiRequest
|
||||
{
|
||||
/**
|
||||
* The resource that should be checked when performing the authorization
|
||||
* function for this request.
|
||||
*/
|
||||
protected ?string $resource;
|
||||
|
||||
/**
|
||||
* The permission level that a given API key should have for accessing
|
||||
* the defined $resource during the request cycle.
|
||||
*/
|
||||
protected int $permission = AdminAcl::NONE;
|
||||
|
||||
/**
|
||||
* Determine if the current user is authorized to perform
|
||||
* the requested action against the API.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\PterodactylException
|
||||
* This will eventually be replaced with per-request permissions checking
|
||||
* on the API key and for the user.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
if (is_null($this->resource)) {
|
||||
throw new PterodactylException('An ACL resource must be defined on API requests.');
|
||||
}
|
||||
|
||||
$token = $this->user()->currentAccessToken();
|
||||
if ($token instanceof TransientToken) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($token->key_type === ApiKey::TYPE_ACCOUNT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return AdminAcl::check($token, $this->resource, $this->permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default set of rules to apply to API requests.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method allowing a developer to easily hook into this logic without having
|
||||
* to remember what the method name is called or where to use it. By default this is
|
||||
* a no-op.
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the named route parameter and asserts that it is a real model that
|
||||
* exists in the database.
|
||||
*
|
||||
* @template T of \Illuminate\Database\Eloquent\Model
|
||||
*
|
||||
* @param class-string<T> $expect
|
||||
*
|
||||
* @return T
|
||||
*
|
||||
* @noinspection PhpDocSignatureInspection
|
||||
*/
|
||||
public function parameter(string $key, string $expect)
|
||||
{
|
||||
$value = $this->route()->parameter($key);
|
||||
|
||||
Assert::isInstanceOf($value, $expect);
|
||||
Assert::isInstanceOf($value, Model::class);
|
||||
Assert::true($value->exists);
|
||||
|
||||
/* @var T $value */
|
||||
return $value;
|
||||
return $this->user()->root_admin;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Databases;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class DeleteDatabaseRequest extends ApplicationApiRequest
|
||||
{
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Databases;
|
||||
|
||||
class GetDatabaseRequest extends GetDatabasesRequest
|
||||
{
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Databases;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetDatabasesRequest extends ApplicationApiRequest
|
||||
{
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Databases;
|
||||
|
||||
use Pterodactyl\Models\DatabaseHost;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreDatabaseRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return $rules ?? DatabaseHost::getRules();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Databases;
|
||||
|
||||
use Pterodactyl\Models\DatabaseHost;
|
||||
|
||||
class UpdateDatabaseRequest extends StoreDatabaseRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return $rules ?? DatabaseHost::getRulesForUpdate($this->route()->parameter('databaseHost'));
|
||||
}
|
||||
}
|
16
app/Http/Requests/Api/Application/Eggs/DeleteEggRequest.php
Normal file
16
app/Http/Requests/Api/Application/Eggs/DeleteEggRequest.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
|
||||
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class DeleteEggRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function resourceExists(): bool
|
||||
{
|
||||
$egg = $this->route()->parameter('egg');
|
||||
|
||||
return $egg instanceof Egg && $egg->exists;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class ExportEggRequest extends ApplicationApiRequest
|
||||
{
|
||||
}
|
7
app/Http/Requests/Api/Application/Eggs/GetEggRequest.php
Normal file
7
app/Http/Requests/Api/Application/Eggs/GetEggRequest.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
|
||||
|
||||
class GetEggRequest extends GetEggsRequest
|
||||
{
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetEggsRequest extends ApplicationApiRequest
|
||||
{
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class ImportEggRequest extends ApplicationApiRequest
|
||||
{
|
||||
}
|
30
app/Http/Requests/Api/Application/Eggs/StoreEggRequest.php
Normal file
30
app/Http/Requests/Api/Application/Eggs/StoreEggRequest.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreEggRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return [
|
||||
'nest_id' => 'required|bail|numeric|exists:nests,id',
|
||||
'name' => 'required|string|max:191',
|
||||
'description' => 'sometimes|string|nullable',
|
||||
'features' => 'sometimes|array',
|
||||
'docker_images' => 'required|array|min:1',
|
||||
'docker_images.*' => 'required|string',
|
||||
'file_denylist' => 'sometimes|array|nullable',
|
||||
'file_denylist.*' => 'sometimes|string',
|
||||
'config_files' => 'required|nullable|json',
|
||||
'config_startup' => 'required|nullable|json',
|
||||
'config_stop' => 'required|nullable|string|max:191',
|
||||
// 'config_from' => 'sometimes|nullable|numeric|exists:eggs,id',
|
||||
'startup' => 'required|string',
|
||||
'script_container' => 'sometimes|string',
|
||||
'script_entry' => 'sometimes|string',
|
||||
'script_install' => 'sometimes|string',
|
||||
];
|
||||
}
|
||||
}
|
28
app/Http/Requests/Api/Application/Eggs/UpdateEggRequest.php
Normal file
28
app/Http/Requests/Api/Application/Eggs/UpdateEggRequest.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
|
||||
|
||||
class UpdateEggRequest extends StoreEggRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return [
|
||||
'nest_id' => 'sometimes|numeric|exists:nests,id',
|
||||
'name' => 'sometimes|string|max:191',
|
||||
'description' => 'sometimes|string|nullable',
|
||||
'features' => 'sometimes|array',
|
||||
'docker_images' => 'sometimes|array|min:1',
|
||||
'docker_images.*' => 'sometimes|string',
|
||||
'file_denylist' => 'sometimes|array|nullable',
|
||||
'file_denylist.*' => 'sometimes|string',
|
||||
'config_files' => 'sometimes|nullable|json',
|
||||
'config_startup' => 'sometimes|nullable|json',
|
||||
'config_stop' => 'sometimes|nullable|string|max:191',
|
||||
// 'config_from' => 'sometimes|nullable|numeric|exists:eggs,id',
|
||||
'startup' => 'sometimes|string',
|
||||
'script_container' => 'sometimes|string',
|
||||
'script_entry' => 'sometimes|string',
|
||||
'script_install' => 'sometimes|string',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Eggs\Variables;
|
||||
|
||||
use Pterodactyl\Models\EggVariable;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreEggVariableRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|min:1|max:191',
|
||||
'description' => 'sometimes|string|nullable',
|
||||
'env_variable' => 'required|regex:/^[\w]{1,191}$/|notIn:' . EggVariable::RESERVED_ENV_NAMES,
|
||||
'default_value' => 'present',
|
||||
'user_viewable' => 'required|boolean',
|
||||
'user_editable' => 'required|boolean',
|
||||
'rules' => 'bail|required|string',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Eggs\Variables;
|
||||
|
||||
use Pterodactyl\Models\EggVariable;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class UpdateEggVariablesRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return [
|
||||
'*' => 'array',
|
||||
'*.id' => 'required|integer',
|
||||
'*.name' => 'sometimes|string|min:1|max:191',
|
||||
'*.description' => 'sometimes|string|nullable',
|
||||
'*.env_variable' => 'sometimes|regex:/^[\w]{1,191}$/|notIn:' . EggVariable::RESERVED_ENV_NAMES,
|
||||
'*.default_value' => 'sometimes|present',
|
||||
'*.user_viewable' => 'sometimes|boolean',
|
||||
'*.user_editable' => 'sometimes|boolean',
|
||||
'*.rules' => 'sometimes|string',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Locations;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class DeleteLocationRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_LOCATIONS;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Locations;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetLocationsRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_LOCATIONS;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
||||
|
|
|
@ -3,18 +3,10 @@
|
|||
namespace Pterodactyl\Http\Requests\Api\Application\Locations;
|
||||
|
||||
use Pterodactyl\Models\Location;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreLocationRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_LOCATIONS;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
|
||||
/**
|
||||
* Rules to validate the request against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return collect(Location::getRules())->only([
|
||||
|
@ -23,9 +15,6 @@ class StoreLocationRequest extends ApplicationApiRequest
|
|||
])->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename fields to be more clear in error messages.
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
@ -6,12 +6,9 @@ use Pterodactyl\Models\Location;
|
|||
|
||||
class UpdateLocationRequest extends StoreLocationRequest
|
||||
{
|
||||
/**
|
||||
* Rules to validate this request against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$locationId = $this->route()->parameter('location')->id;
|
||||
$locationId = $this->route()->parameter('location');
|
||||
|
||||
return collect(Location::getRulesForUpdate($locationId))->only([
|
||||
'short',
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class DeleteMountRequest extends ApplicationApiRequest
|
||||
{
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
|
||||
|
||||
class GetMountRequest extends GetMountsRequest
|
||||
{
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetMountsRequest extends ApplicationApiRequest
|
||||
{
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class MountEggsRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return $rules ?? ['eggs' => 'required|exists:eggs,id'];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class MountNodesRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return $rules ?? ['nodes' => 'required|exists:nodes,id'];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
|
||||
|
||||
use Pterodactyl\Models\Mount;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreMountRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return $rules ?? Mount::getRules();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
|
||||
|
||||
use Pterodactyl\Models\Mount;
|
||||
|
||||
class UpdateMountRequest extends StoreMountRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return $rules ?? Mount::getRulesForUpdate($this->route()->parameter('mount'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Nests;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class DeleteNestRequest extends ApplicationApiRequest
|
||||
{
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Nests\Eggs;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetEggRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_EGGS;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Nests\Eggs;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetEggsRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_EGGS;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Nests;
|
||||
|
||||
class GetNestRequest extends GetNestsRequest
|
||||
{
|
||||
}
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Nests;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetNestsRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_NESTS;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
||||
|
|
14
app/Http/Requests/Api/Application/Nests/StoreNestRequest.php
Normal file
14
app/Http/Requests/Api/Application/Nests/StoreNestRequest.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Nests;
|
||||
|
||||
use Pterodactyl\Models\Nest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreNestRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return $rules ?? Nest::getRules();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Nests;
|
||||
|
||||
use Pterodactyl\Models\Nest;
|
||||
|
||||
class UpdateNestRequest extends StoreNestRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return $rules ?? Nest::getRulesForUpdate($this->route()->parameter('nest'));
|
||||
}
|
||||
}
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Nodes;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class DeleteNodeRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_NODES;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Nodes;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetNodesRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_NODES;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
||||
|
|
|
@ -2,39 +2,40 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Nodes;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreNodeRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_NODES;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
|
||||
/**
|
||||
* Validation rules to apply to this request.
|
||||
*/
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return collect($rules ?? Node::getRules())->only([
|
||||
'public',
|
||||
'name',
|
||||
'description',
|
||||
'location_id',
|
||||
'database_host_id',
|
||||
'fqdn',
|
||||
'scheme',
|
||||
'behind_proxy',
|
||||
'public',
|
||||
|
||||
'listen_port_http',
|
||||
'public_port_http',
|
||||
'listen_port_sftp',
|
||||
'public_port_sftp',
|
||||
|
||||
'memory',
|
||||
'memory_overallocate',
|
||||
'disk',
|
||||
'disk_overallocate',
|
||||
'upload_size',
|
||||
'daemonListen',
|
||||
'daemonSFTP',
|
||||
'daemonBase',
|
||||
])->mapWithKeys(function ($value, $key) {
|
||||
$key = ($key === 'daemonSFTP') ? 'daemonSftp' : $key;
|
||||
|
||||
'upload_size',
|
||||
'daemon_base',
|
||||
])->mapWithKeys(function ($value, $key) {
|
||||
return [snake_case($key) => $value];
|
||||
})->toArray();
|
||||
}
|
||||
|
@ -59,11 +60,11 @@ class StoreNodeRequest extends ApplicationApiRequest
|
|||
public function validated($key = null, $default = null): array
|
||||
{
|
||||
$response = parent::validated();
|
||||
$response['daemonListen'] = $response['daemon_listen'];
|
||||
$response['daemonSFTP'] = $response['daemon_sftp'];
|
||||
$response['daemonBase'] = $response['daemon_base'] ?? (new Node())->getAttribute('daemonBase');
|
||||
$response['daemon_base'] = $response['daemon_base'] ?? Node::DEFAULT_DAEMON_BASE;
|
||||
|
||||
unset($response['daemon_base'], $response['daemon_listen'], $response['daemon_sftp']);
|
||||
if (!is_null($key)) {
|
||||
return Arr::get($response, $key, $default);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
|
|
@ -6,14 +6,8 @@ use Pterodactyl\Models\Node;
|
|||
|
||||
class UpdateNodeRequest extends StoreNodeRequest
|
||||
{
|
||||
/**
|
||||
* Apply validation rules to this request. Uses the parent class rules()
|
||||
* function but passes in the rules for updating rather than creating.
|
||||
*/
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
$node = $this->route()->parameter('node')->id;
|
||||
|
||||
return parent::rules(Node::getRulesForUpdate($node));
|
||||
return parent::rules($rules ?? Node::getRulesForUpdate($this->route()->parameter('node')));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class DeleteRoleRequest extends ApplicationApiRequest
|
||||
{
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
|
||||
|
||||
class GetRoleRequest extends GetRolesRequest
|
||||
{
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
|
||||
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetRolesRequest extends ApplicationApiRequest
|
||||
{
|
||||
}
|
14
app/Http/Requests/Api/Application/Roles/StoreRoleRequest.php
Normal file
14
app/Http/Requests/Api/Application/Roles/StoreRoleRequest.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
|
||||
|
||||
use Pterodactyl\Models\AdminRole;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreRoleRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return $rules ?? AdminRole::getRules();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
|
||||
|
||||
use Pterodactyl\Models\AdminRole;
|
||||
|
||||
class UpdateRoleRequest extends StoreRoleRequest
|
||||
{
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
return $rules ?? AdminRole::getRulesForUpdate($this->route()->parameter('role'));
|
||||
}
|
||||
}
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers\Databases;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetServerDatabaseRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_SERVER_DATABASES;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers\Databases;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetServerDatabasesRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_SERVER_DATABASES;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers\Databases;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
|
||||
class ServerDatabaseWriteRequest extends GetServerDatabasesRequest
|
||||
{
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
}
|
||||
|
|
|
@ -2,25 +2,19 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers\Databases;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Webmozart\Assert\Assert;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Services\Databases\DatabaseManagementService;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreServerDatabaseRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_SERVER_DATABASES;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
|
||||
/**
|
||||
* Validation rules for database creation.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var \Pterodactyl\Models\Server $server */
|
||||
$server = $this->route()->parameter('server');
|
||||
|
||||
return [
|
||||
|
@ -39,20 +33,22 @@ class StoreServerDatabaseRequest extends ApplicationApiRequest
|
|||
}
|
||||
|
||||
/**
|
||||
* Return data formatted in the correct format for the service to consume.
|
||||
* @param string|null $key
|
||||
* @param string|array|null $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function validated($key = null, $default = null): array
|
||||
public function validated($key = null, $default = null)
|
||||
{
|
||||
return [
|
||||
$data = [
|
||||
'database' => $this->input('database'),
|
||||
'remote' => $this->input('remote'),
|
||||
'database_host_id' => $this->input('host'),
|
||||
];
|
||||
|
||||
return is_null($key) ? $data : Arr::get($data, $key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format error messages in a more understandable format for API output.
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
|
@ -62,9 +58,6 @@ class StoreServerDatabaseRequest extends ApplicationApiRequest
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database name in the expected format.
|
||||
*/
|
||||
public function databaseName(): string
|
||||
{
|
||||
$server = $this->route()->parameter('server');
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetExternalServerRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_SERVERS;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetServerRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_SERVERS;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class ServerWriteRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_SERVERS;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
}
|
||||
|
|
|
@ -2,22 +2,12 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Models\Objects\DeploymentObject;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreServerRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_SERVERS;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
|
||||
/**
|
||||
* Rules to be applied to this request.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = Server::getRules();
|
||||
|
@ -26,15 +16,9 @@ class StoreServerRequest extends ApplicationApiRequest
|
|||
'external_id' => $rules['external_id'],
|
||||
'name' => $rules['name'],
|
||||
'description' => array_merge(['nullable'], $rules['description']),
|
||||
'user' => $rules['owner_id'],
|
||||
'egg' => $rules['egg_id'],
|
||||
'docker_image' => $rules['image'],
|
||||
'startup' => $rules['startup'],
|
||||
'environment' => 'present|array',
|
||||
'skip_scripts' => 'sometimes|boolean',
|
||||
'oom_disabled' => 'sometimes|boolean',
|
||||
'owner_id' => $rules['owner_id'],
|
||||
'node_id' => $rules['node_id'],
|
||||
|
||||
// Resource limitations
|
||||
'limits' => 'required|array',
|
||||
'limits.memory' => $rules['memory'],
|
||||
'limits.swap' => $rules['swap'],
|
||||
|
@ -42,110 +26,64 @@ class StoreServerRequest extends ApplicationApiRequest
|
|||
'limits.io' => $rules['io'],
|
||||
'limits.threads' => $rules['threads'],
|
||||
'limits.cpu' => $rules['cpu'],
|
||||
'limits.oom_killer' => 'required|boolean',
|
||||
|
||||
// Application Resource Limits
|
||||
'feature_limits' => 'required|array',
|
||||
'feature_limits.databases' => $rules['database_limit'],
|
||||
'feature_limits.allocations' => $rules['allocation_limit'],
|
||||
'feature_limits.backups' => $rules['backup_limit'],
|
||||
'feature_limits.databases' => $rules['database_limit'],
|
||||
|
||||
// Placeholders for rules added in withValidator() function.
|
||||
'allocation.default' => '',
|
||||
'allocation.additional.*' => '',
|
||||
'allocation.default' => 'required|bail|integer|exists:allocations,id',
|
||||
'allocation.additional.*' => 'integer|exists:allocations,id',
|
||||
|
||||
// Automatic deployment rules
|
||||
'deploy' => 'sometimes|required|array',
|
||||
'deploy.locations' => 'array',
|
||||
'deploy.locations.*' => 'integer|min:1',
|
||||
'deploy.dedicated_ip' => 'required_with:deploy,boolean',
|
||||
'deploy.port_range' => 'array',
|
||||
'deploy.port_range.*' => 'string',
|
||||
|
||||
'start_on_completion' => 'sometimes|boolean',
|
||||
'startup' => $rules['startup'],
|
||||
'environment' => 'present|array',
|
||||
'egg_id' => $rules['egg_id'],
|
||||
'image' => $rules['image'],
|
||||
'skip_scripts' => 'present|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the data into a format that can be consumed by the service.
|
||||
* @param string|null $key
|
||||
* @param string|array|null $default
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function validated($key = null, $default = null): array
|
||||
public function validated($key = null, $default = null)
|
||||
{
|
||||
$data = parent::validated();
|
||||
|
||||
return [
|
||||
$response = [
|
||||
'external_id' => array_get($data, 'external_id'),
|
||||
'name' => array_get($data, 'name'),
|
||||
'description' => array_get($data, 'description'),
|
||||
'owner_id' => array_get($data, 'user'),
|
||||
'egg_id' => array_get($data, 'egg'),
|
||||
'image' => array_get($data, 'docker_image'),
|
||||
'startup' => array_get($data, 'startup'),
|
||||
'environment' => array_get($data, 'environment'),
|
||||
'owner_id' => array_get($data, 'owner_id'),
|
||||
'node_id' => array_get($data, 'node_id'),
|
||||
|
||||
'memory' => array_get($data, 'limits.memory'),
|
||||
'swap' => array_get($data, 'limits.swap'),
|
||||
'disk' => array_get($data, 'limits.disk'),
|
||||
'io' => array_get($data, 'limits.io'),
|
||||
'cpu' => array_get($data, 'limits.cpu'),
|
||||
'threads' => array_get($data, 'limits.threads'),
|
||||
'skip_scripts' => array_get($data, 'skip_scripts', false),
|
||||
'allocation_id' => array_get($data, 'allocation.default'),
|
||||
'allocation_additional' => array_get($data, 'allocation.additional'),
|
||||
'start_on_completion' => array_get($data, 'start_on_completion', false),
|
||||
'database_limit' => array_get($data, 'feature_limits.databases'),
|
||||
'cpu' => array_get($data, 'limits.cpu'),
|
||||
'oom_killer' => array_get($data, 'limits.oom_killer'),
|
||||
|
||||
'allocation_limit' => array_get($data, 'feature_limits.allocations'),
|
||||
'backup_limit' => array_get($data, 'feature_limits.backups'),
|
||||
'oom_disabled' => array_get($data, 'oom_disabled'),
|
||||
'database_limit' => array_get($data, 'feature_limits.databases'),
|
||||
|
||||
'allocation_id' => array_get($data, 'allocation.default'),
|
||||
'allocation_additional' => array_get($data, 'allocation.additional'),
|
||||
|
||||
'startup' => array_get($data, 'startup'),
|
||||
'environment' => array_get($data, 'environment'),
|
||||
'egg_id' => array_get($data, 'egg_id'),
|
||||
'image' => array_get($data, 'image'),
|
||||
'skip_scripts' => array_get($data, 'skip_scripts'),
|
||||
'start_on_completion' => array_get($data, 'start_on_completion', false),
|
||||
];
|
||||
}
|
||||
|
||||
/*
|
||||
* Run validation after the rules above have been applied.
|
||||
*
|
||||
* @param \Illuminate\Validation\Validator $validator
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->sometimes('allocation.default', [
|
||||
'required', 'integer', 'bail',
|
||||
Rule::exists('allocations', 'id')->where(function ($query) {
|
||||
$query->whereNull('server_id');
|
||||
}),
|
||||
], function ($input) {
|
||||
return !$input->deploy;
|
||||
});
|
||||
|
||||
$validator->sometimes('allocation.additional.*', [
|
||||
'integer',
|
||||
Rule::exists('allocations', 'id')->where(function ($query) {
|
||||
$query->whereNull('server_id');
|
||||
}),
|
||||
], function ($input) {
|
||||
return !$input->deploy;
|
||||
});
|
||||
|
||||
$validator->sometimes('deploy.locations', 'present', function ($input) {
|
||||
return $input->deploy;
|
||||
});
|
||||
|
||||
$validator->sometimes('deploy.port_range', 'present', function ($input) {
|
||||
return $input->deploy;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a deployment object that can be passed to the server creation service.
|
||||
*/
|
||||
public function getDeploymentObject(): ?DeploymentObject
|
||||
{
|
||||
if (is_null($this->input('deploy'))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$object = new DeploymentObject();
|
||||
$object->setDedicated($this->input('deploy.dedicated_ip', false));
|
||||
$object->setLocations($this->input('deploy.locations', []));
|
||||
$object->setPorts($this->input('deploy.port_range', []));
|
||||
|
||||
return $object;
|
||||
return is_null($key) ? $response : Arr::get($response, $key, $default);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers;
|
||||
|
||||
use Pterodactyl\Models\Server;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class UpdateServerBuildConfigurationRequest extends ServerWriteRequest
|
||||
{
|
||||
/**
|
||||
* Return the rules to validate this request against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = Server::getRulesForUpdate($this->parameter('server', Server::class));
|
||||
|
||||
return [
|
||||
'allocation' => $rules['allocation_id'],
|
||||
'oom_disabled' => $rules['oom_disabled'],
|
||||
|
||||
'limits' => 'sometimes|array',
|
||||
'limits.memory' => $this->requiredToOptional('memory', $rules['memory'], true),
|
||||
'limits.swap' => $this->requiredToOptional('swap', $rules['swap'], true),
|
||||
'limits.io' => $this->requiredToOptional('io', $rules['io'], true),
|
||||
'limits.cpu' => $this->requiredToOptional('cpu', $rules['cpu'], true),
|
||||
'limits.threads' => $this->requiredToOptional('threads', $rules['threads'], true),
|
||||
'limits.disk' => $this->requiredToOptional('disk', $rules['disk'], true),
|
||||
|
||||
// Legacy rules to maintain backwards compatable API support without requiring
|
||||
// a major version bump.
|
||||
//
|
||||
// @see https://github.com/pterodactyl/panel/issues/1500
|
||||
'memory' => $this->requiredToOptional('memory', $rules['memory']),
|
||||
'swap' => $this->requiredToOptional('swap', $rules['swap']),
|
||||
'io' => $this->requiredToOptional('io', $rules['io']),
|
||||
'cpu' => $this->requiredToOptional('cpu', $rules['cpu']),
|
||||
'threads' => $this->requiredToOptional('threads', $rules['threads']),
|
||||
'disk' => $this->requiredToOptional('disk', $rules['disk']),
|
||||
|
||||
'add_allocations' => 'bail|array',
|
||||
'add_allocations.*' => 'integer',
|
||||
'remove_allocations' => 'bail|array',
|
||||
'remove_allocations.*' => 'integer',
|
||||
|
||||
'feature_limits' => 'required|array',
|
||||
'feature_limits.databases' => $rules['database_limit'],
|
||||
'feature_limits.allocations' => $rules['allocation_limit'],
|
||||
'feature_limits.backups' => $rules['backup_limit'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the allocation field into the expected format for the service handler.
|
||||
*/
|
||||
public function validated($key = null, $default = null): array
|
||||
{
|
||||
$data = parent::validated();
|
||||
|
||||
$data['allocation_id'] = $data['allocation'];
|
||||
$data['database_limit'] = $data['feature_limits']['databases'] ?? null;
|
||||
$data['allocation_limit'] = $data['feature_limits']['allocations'] ?? null;
|
||||
$data['backup_limit'] = $data['feature_limits']['backups'] ?? null;
|
||||
unset($data['allocation'], $data['feature_limits']);
|
||||
|
||||
// Adjust the limits field to match what is expected by the model.
|
||||
if (!empty($data['limits'])) {
|
||||
foreach ($data['limits'] as $key => $value) {
|
||||
$data[$key] = $value;
|
||||
}
|
||||
|
||||
unset($data['limits']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom attributes to use in error message responses.
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'add_allocations' => 'allocations to add',
|
||||
'remove_allocations' => 'allocations to remove',
|
||||
'add_allocations.*' => 'allocation to add',
|
||||
'remove_allocations.*' => 'allocation to remove',
|
||||
'feature_limits.databases' => 'Database Limit',
|
||||
'feature_limits.allocations' => 'Allocation Limit',
|
||||
'feature_limits.backups' => 'Backup Limit',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts existing rules for certain limits into a format that maintains backwards
|
||||
* compatability with the old API endpoint while also supporting a more correct API
|
||||
* call.
|
||||
*
|
||||
* @see https://github.com/pterodactyl/panel/issues/1500
|
||||
*/
|
||||
protected function requiredToOptional(string $field, array $rules, bool $limits = false): array
|
||||
{
|
||||
if (!in_array('required', $rules)) {
|
||||
return $rules;
|
||||
}
|
||||
|
||||
return (new Collection($rules))
|
||||
->filter(function ($value) {
|
||||
return $value !== 'required';
|
||||
})
|
||||
->prepend($limits ? 'required_with:limits' : 'required_without:limits')
|
||||
->toArray();
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers;
|
||||
|
||||
use Pterodactyl\Models\Server;
|
||||
|
||||
class UpdateServerDetailsRequest extends ServerWriteRequest
|
||||
{
|
||||
/**
|
||||
* Rules to apply to a server details update request.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = Server::getRulesForUpdate($this->parameter('server', Server::class));
|
||||
|
||||
return [
|
||||
'external_id' => $rules['external_id'],
|
||||
'name' => $rules['name'],
|
||||
'user' => $rules['owner_id'],
|
||||
'description' => array_merge(['nullable'], $rules['description']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the posted data into the correct format that is expected
|
||||
* by the application.
|
||||
*/
|
||||
public function validated($key = null, $default = null): array
|
||||
{
|
||||
return [
|
||||
'external_id' => $this->input('external_id'),
|
||||
'name' => $this->input('name'),
|
||||
'owner_id' => $this->input('user'),
|
||||
'description' => $this->input('description'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename some attributes in error messages to clarify the field
|
||||
* being discussed.
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'user' => 'User ID',
|
||||
'name' => 'Server Name',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Servers;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class UpdateServerRequest extends ApplicationApiRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = Server::getRules();
|
||||
|
||||
return [
|
||||
'external_id' => $rules['external_id'],
|
||||
'name' => $rules['name'],
|
||||
'description' => array_merge(['nullable'], $rules['description']),
|
||||
'owner_id' => $rules['owner_id'],
|
||||
|
||||
'limits' => 'sometimes|array',
|
||||
'limits.memory' => $rules['memory'],
|
||||
'limits.swap' => $rules['swap'],
|
||||
'limits.disk' => $rules['disk'],
|
||||
'limits.io' => $rules['io'],
|
||||
'limits.threads' => $rules['threads'],
|
||||
'limits.cpu' => $rules['cpu'],
|
||||
'limits.oom_killer' => 'sometimes|boolean',
|
||||
|
||||
'feature_limits' => 'required|array',
|
||||
'feature_limits.allocations' => $rules['allocation_limit'],
|
||||
'feature_limits.backups' => $rules['backup_limit'],
|
||||
'feature_limits.databases' => $rules['database_limit'],
|
||||
|
||||
'allocation_id' => 'bail|exists:allocations,id',
|
||||
'add_allocations' => 'bail|array',
|
||||
'add_allocations.*' => 'integer',
|
||||
'remove_allocations' => 'bail|array',
|
||||
'remove_allocations.*' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $key
|
||||
* @param string|array|null $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function validated($key = null, $default = null)
|
||||
{
|
||||
$data = parent::validated();
|
||||
$response = [
|
||||
'external_id' => array_get($data, 'external_id'),
|
||||
'name' => array_get($data, 'name'),
|
||||
'description' => array_get($data, 'description'),
|
||||
'owner_id' => array_get($data, 'owner_id'),
|
||||
|
||||
'memory' => array_get($data, 'limits.memory'),
|
||||
'swap' => array_get($data, 'limits.swap'),
|
||||
'disk' => array_get($data, 'limits.disk'),
|
||||
'io' => array_get($data, 'limits.io'),
|
||||
'threads' => array_get($data, 'limits.threads'),
|
||||
'cpu' => array_get($data, 'limits.cpu'),
|
||||
'oom_killer' => array_get($data, 'limits.oom_killer'),
|
||||
|
||||
'allocation_limit' => array_get($data, 'feature_limits.allocations'),
|
||||
'backup_limit' => array_get($data, 'feature_limits.backups'),
|
||||
'database_limit' => array_get($data, 'feature_limits.databases'),
|
||||
|
||||
'allocation_id' => array_get($data, 'allocation_id'),
|
||||
'add_allocations' => array_get($data, 'add_allocations'),
|
||||
'remove_allocations' => array_get($data, 'remove_allocations'),
|
||||
];
|
||||
|
||||
return is_null($key) ? $response : Arr::get($response, $key, $default);
|
||||
}
|
||||
}
|
|
@ -3,41 +3,20 @@
|
|||
namespace Pterodactyl\Http\Requests\Api\Application\Servers;
|
||||
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class UpdateServerStartupRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_SERVERS;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
|
||||
/**
|
||||
* Validation rules to run the input against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$data = Server::getRulesForUpdate($this->parameter('server', Server::class));
|
||||
$rules = Server::getRulesForUpdate($this->route()->parameter('server'));
|
||||
|
||||
return [
|
||||
'startup' => $data['startup'],
|
||||
'startup' => $rules['startup'],
|
||||
'environment' => 'present|array',
|
||||
'egg' => $data['egg_id'],
|
||||
'image' => $data['image'],
|
||||
'egg_id' => $rules['egg_id'],
|
||||
'image' => $rules['image'],
|
||||
'skip_scripts' => 'present|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the validated data in a format that is expected by the service.
|
||||
*/
|
||||
public function validated($key = null, $default = null): array
|
||||
{
|
||||
$data = parent::validated();
|
||||
|
||||
return collect($data)->only(['startup', 'environment', 'skip_scripts'])->merge([
|
||||
'egg_id' => array_get($data, 'egg'),
|
||||
'docker_image' => array_get($data, 'image'),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Users;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class DeleteUserRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_USERS;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Users;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetExternalUserRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_USERS;
|
||||
|
||||
protected int $permission = AdminAcl::READ;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Users;
|
||||
|
||||
class GetUserRequest extends GetUsersRequest
|
||||
{
|
||||
}
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Application\Users;
|
||||
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl as Acl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class GetUsersRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = Acl::RESOURCE_USERS;
|
||||
|
||||
protected int $permission = Acl::READ;
|
||||
}
|
||||
|
|
|
@ -3,59 +3,21 @@
|
|||
namespace Pterodactyl\Http\Requests\Api\Application\Users;
|
||||
|
||||
use Pterodactyl\Models\User;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||
|
||||
class StoreUserRequest extends ApplicationApiRequest
|
||||
{
|
||||
protected ?string $resource = AdminAcl::RESOURCE_USERS;
|
||||
|
||||
protected int $permission = AdminAcl::WRITE;
|
||||
|
||||
/**
|
||||
* Return the validation rules for this request.
|
||||
*/
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
$rules = $rules ?? User::getRules();
|
||||
|
||||
$response = collect($rules)->only([
|
||||
return collect($rules)->only([
|
||||
'external_id',
|
||||
'email',
|
||||
'username',
|
||||
'password',
|
||||
'language',
|
||||
'admin_role_id',
|
||||
'root_admin',
|
||||
])->toArray();
|
||||
|
||||
$response['first_name'] = $rules['name_first'];
|
||||
$response['last_name'] = $rules['name_last'];
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function validated($key = null, $default = null): array
|
||||
{
|
||||
$data = parent::validated();
|
||||
|
||||
$data['name_first'] = $data['first_name'];
|
||||
$data['name_last'] = $data['last_name'];
|
||||
|
||||
unset($data['first_name'], $data['last_name']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename some fields to be more user friendly.
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'external_id' => 'Third Party Identifier',
|
||||
'name_first' => 'First Name',
|
||||
'name_last' => 'Last Name',
|
||||
'root_admin' => 'Root Administrator Status',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,8 @@ use Pterodactyl\Models\User;
|
|||
|
||||
class UpdateUserRequest extends StoreUserRequest
|
||||
{
|
||||
/**
|
||||
* Return the validation rules for this request.
|
||||
*/
|
||||
public function rules(array $rules = null): array
|
||||
{
|
||||
$userId = $this->parameter('user', User::class)->id;
|
||||
|
||||
return parent::rules(User::getRulesForUpdate($userId));
|
||||
return parent::rules($rules ?? User::getRulesForUpdate($this->route()->parameter('user')));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Pterodactyl\Http\Requests\Api\Client\Account;
|
||||
|
||||
use Exception;
|
||||
use phpseclib3\Crypt\DSA;
|
||||
use phpseclib3\Crypt\RSA;
|
||||
use Pterodactyl\Models\UserSSHKey;
|
||||
|
@ -71,7 +70,7 @@ class StoreSSHKeyRequest extends ClientApiRequest
|
|||
public function getKeyFingerprint(): string
|
||||
{
|
||||
if (!$this->key) {
|
||||
throw new Exception('The public key was not properly loaded for this request.');
|
||||
throw new \Exception('The public key was not properly loaded for this request.');
|
||||
}
|
||||
|
||||
return $this->key->getFingerprint('sha256');
|
||||
|
|
|
@ -11,6 +11,7 @@ use Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException;
|
|||
class UpdateEmailRequest extends ClientApiRequest
|
||||
{
|
||||
/**
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
* @throws \Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException
|
||||
*/
|
||||
public function authorize(): bool
|
||||
|
|
|
@ -21,6 +21,7 @@ class StoreDatabaseRequest extends ClientApiRequest implements ClientPermissions
|
|||
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var Server $server */
|
||||
$server = $this->route()->parameter('server');
|
||||
|
||||
Assert::isInstanceOf($server, Server::class);
|
||||
|
|
|
@ -13,6 +13,6 @@ class DownloadFileRequest extends ClientApiRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user()->can('file.read', $this->parameter('server', Server::class));
|
||||
return $this->user()->can('file.read', $this->route()->parameter('server'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,6 @@ abstract class SubuserRequest extends ClientApiRequest
|
|||
// Otherwise, get the current subuser's permission set, and ensure that the
|
||||
// permissions they are trying to assign are not _more_ than the ones they
|
||||
// already have.
|
||||
/** @var \Pterodactyl\Models\Subuser|null $subuser */
|
||||
/** @var \Pterodactyl\Services\Servers\GetUserPermissionsService $service */
|
||||
$service = $this->container->make(GetUserPermissionsService::class);
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@ class ActivityEventRequest extends FormRequest
|
|||
return [
|
||||
'data' => ['required', 'array'],
|
||||
'data.*' => ['array'],
|
||||
'data.*.user' => ['present', 'uuid'],
|
||||
'data.*.user' => ['sometimes', 'nullable', 'uuid'],
|
||||
'data.*.server' => ['required', 'uuid'],
|
||||
'data.*.event' => ['required', 'string'],
|
||||
'data.*.metadata' => ['present', 'nullable', 'array'],
|
||||
'data.*.ip' => ['present', 'ip'],
|
||||
'data.*.ip' => ['sometimes', 'nullable', 'ip'],
|
||||
'data.*.timestamp' => ['required', 'string'],
|
||||
];
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ class InstallationDataRequest extends FormRequest
|
|||
{
|
||||
return [
|
||||
'successful' => 'present|boolean',
|
||||
'reinstall' => 'sometimes|boolean',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue