Update existing application API to use simplified user permission checking

This commit is contained in:
Dane Everitt 2021-08-04 21:14:14 -07:00
parent 622d292f39
commit 47b895a98a
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
57 changed files with 109 additions and 532 deletions

View file

@ -1,13 +0,0 @@
<?php
namespace Pterodactyl\Contracts\Http;
interface ClientPermissionsRequest
{
/**
* Returns the permissions string indicating which permission should be used to
* validate that the authenticated user has permission to perform this action aganist
* the given resource (server).
*/
public function permission(): string;
}

View file

@ -2,6 +2,7 @@
namespace Pterodactyl\Http\Controllers\Api\Application\Servers; namespace Pterodactyl\Http\Controllers\Api\Application\Servers;
use Pterodactyl\Models\Server;
use Pterodactyl\Transformers\Api\Application\ServerTransformer; use Pterodactyl\Transformers\Api\Application\ServerTransformer;
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController; use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
use Pterodactyl\Http\Requests\Api\Application\Servers\GetExternalServerRequest; use Pterodactyl\Http\Requests\Api\Application\Servers\GetExternalServerRequest;
@ -13,9 +14,11 @@ class ExternalServerController extends ApplicationApiController
* *
* @throws \Illuminate\Contracts\Container\BindingResolutionException * @throws \Illuminate\Contracts\Container\BindingResolutionException
*/ */
public function index(GetExternalServerRequest $request): array public function index(GetExternalServerRequest $request, string $external_id): array
{ {
return $this->fractal->item($request->getServerModel()) $server = Server::query()->where('external_id', $external_id)->firstOrFail();
return $this->fractal->item($server)
->transformWith($this->getTransformer(ServerTransformer::class)) ->transformWith($this->getTransformer(ServerTransformer::class))
->toArray(); ->toArray();
} }

View file

@ -2,6 +2,7 @@
namespace Pterodactyl\Http\Controllers\Api\Application\Users; namespace Pterodactyl\Http\Controllers\Api\Application\Users;
use Pterodactyl\Models\User;
use Pterodactyl\Transformers\Api\Application\UserTransformer; use Pterodactyl\Transformers\Api\Application\UserTransformer;
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController; use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
use Pterodactyl\Http\Requests\Api\Application\Users\GetExternalUserRequest; use Pterodactyl\Http\Requests\Api\Application\Users\GetExternalUserRequest;
@ -13,9 +14,11 @@ class ExternalUserController extends ApplicationApiController
* *
* @throws \Illuminate\Contracts\Container\BindingResolutionException * @throws \Illuminate\Contracts\Container\BindingResolutionException
*/ */
public function index(GetExternalUserRequest $request): array public function index(GetExternalUserRequest $request, string $external_id): array
{ {
return $this->fractal->item($request->getUserModel()) $user = User::query()->where('external_id', $external_id)->firstOrFail();
return $this->fractal->item($user)
->transformWith($this->getTransformer(UserTransformer::class)) ->transformWith($this->getTransformer(UserTransformer::class))
->toArray(); ->toArray();
} }

View file

@ -74,14 +74,4 @@ class ApiSubstituteBindings extends SubstituteBindings
return $next($request); return $next($request);
} }
/**
* Return the registered mappings.
*
* @return array
*/
public static function getMappings()
{
return self::$mappings;
}
} }

View file

@ -0,0 +1,80 @@
<?php
namespace Pterodactyl\Http\Requests\Api;
use Illuminate\Foundation\Http\FormRequest;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
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;
}
}

View file

@ -2,31 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Allocations; namespace Pterodactyl\Http\Requests\Api\Application\Allocations;
use Pterodactyl\Models\Node;
use Pterodactyl\Models\Allocation;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class DeleteAllocationRequest extends ApplicationApiRequest class DeleteAllocationRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_ALLOCATIONS;
protected int $permission = AdminAcl::WRITE;
/**
* Determine if the requested allocation exists and belongs to the node that
* is being passed in the URL.
*/
public function resourceExists(): bool
{
$node = $this->route()->parameter('node');
$allocation = $this->route()->parameter('allocation');
if ($node instanceof Node && $node->exists) {
if ($allocation instanceof Allocation && $allocation->exists && $allocation->node_id === $node->id) {
return true;
}
}
return false;
}
} }

View file

@ -2,23 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Allocations; namespace Pterodactyl\Http\Requests\Api\Application\Allocations;
use Pterodactyl\Models\Node;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetAllocationsRequest extends ApplicationApiRequest class GetAllocationsRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_ALLOCATIONS;
protected int $permission = AdminAcl::READ;
/**
* Determine if the node that we are requesting the allocations
* for exists on the Panel.
*/
public function resourceExists(): bool
{
$node = $this->route()->parameter('node');
return $node instanceof Node && $node->exists;
}
} }

View file

@ -2,14 +2,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Allocations; namespace Pterodactyl\Http\Requests\Api\Application\Allocations;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreAllocationRequest extends ApplicationApiRequest class StoreAllocationRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_ALLOCATIONS;
protected int $permission = AdminAcl::WRITE;
public function rules(): array public function rules(): array
{ {
return [ return [

View file

@ -2,119 +2,18 @@
namespace Pterodactyl\Http\Requests\Api\Application; namespace Pterodactyl\Http\Requests\Api\Application;
use Pterodactyl\Models\ApiKey; use Pterodactyl\Http\Requests\Api\ApiRequest;
use Illuminate\Foundation\Http\FormRequest;
use Pterodactyl\Http\Middleware\Api\ApiSubstituteBindings;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Exception\InvalidParameterException;
abstract class ApplicationApiRequest extends FormRequest abstract class ApplicationApiRequest extends ApiRequest
{ {
/** /**
* Tracks if the request has been validated internally or not to avoid * This will eventually be replaced with per-request permissions checking
* making duplicate validation calls. * on the API key and for the user.
*/ *
private bool $hasValidated = false; * @return bool
/**
* Determine if the current user is authorized to perform the requested
* action against the API.
*/ */
public function authorize(): bool public function authorize(): bool
{ {
return false; return $this->user()->root_admin;
}
/**
* Determine if the requested resource exists on the server.
*/
public function resourceExists(): bool
{
return true;
}
/**
* Default set of rules to apply to API requests.
*/
public function rules(): array
{
return [];
}
/**
* Return the API key being used for the request.
*/
public function key(): ApiKey
{
return $this->attributes->get('api_key');
}
/**
* Grab a model from the route parameters. If no model is found in the
* binding mappings an exception will be thrown.
*
* @return mixed
*
* @deprecated
*
* @throws \Symfony\Component\Routing\Exception\InvalidParameterException
*/
public function getModel(string $model)
{
$parameterKey = array_get(array_flip(ApiSubstituteBindings::getMappings()), $model);
if (is_null($parameterKey)) {
throw new InvalidParameterException();
}
return $this->route()->parameter($parameterKey);
}
/**
* 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) || !$this->resourceExists()) {
throw new NotFoundHttpException(trans('exceptions.api.resource_not_found'));
}
return true;
} }
} }

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Databases; namespace Pterodactyl\Http\Requests\Api\Application\Databases;
use Pterodactyl\Models\DatabaseHost;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class DeleteDatabaseRequest extends ApplicationApiRequest class DeleteDatabaseRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_DATABASE_HOSTS;
protected int $permission = AdminAcl::WRITE;
public function resourceExists(): bool
{
$databaseHost = $this->route()->parameter('databaseHost');
return $databaseHost instanceof DatabaseHost && $databaseHost->exists;
}
} }

View file

@ -2,14 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Application\Databases; namespace Pterodactyl\Http\Requests\Api\Application\Databases;
use Pterodactyl\Models\DatabaseHost;
class GetDatabaseRequest extends GetDatabasesRequest class GetDatabaseRequest extends GetDatabasesRequest
{ {
public function resourceExists(): bool
{
$databaseHost = $this->route()->parameter('databaseHost');
return $databaseHost instanceof DatabaseHost && $databaseHost->exists;
}
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Databases; namespace Pterodactyl\Http\Requests\Api\Application\Databases;
use Pterodactyl\Services\Acl\Api\AdminAcl as Acl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetDatabasesRequest extends ApplicationApiRequest class GetDatabasesRequest extends ApplicationApiRequest
{ {
protected string $resource = Acl::RESOURCE_DATABASE_HOSTS;
protected int $permission = Acl::READ;
} }

View file

@ -3,14 +3,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Databases; namespace Pterodactyl\Http\Requests\Api\Application\Databases;
use Pterodactyl\Models\DatabaseHost; use Pterodactyl\Models\DatabaseHost;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreDatabaseRequest extends ApplicationApiRequest class StoreDatabaseRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_DATABASE_HOSTS;
protected int $permission = AdminAcl::WRITE;
public function rules(array $rules = null): array public function rules(array $rules = null): array
{ {
return $rules ?? DatabaseHost::getRules(); return $rules ?? DatabaseHost::getRules();

View file

@ -3,14 +3,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Eggs; namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
use Pterodactyl\Models\Egg; use Pterodactyl\Models\Egg;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class DeleteEggRequest extends ApplicationApiRequest class DeleteEggRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_EGGS;
protected int $permission = AdminAcl::WRITE;
public function resourceExists(): bool public function resourceExists(): bool
{ {
$egg = $this->route()->parameter('egg'); $egg = $this->route()->parameter('egg');

View file

@ -2,14 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Application\Eggs; namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
use Pterodactyl\Models\Egg;
class GetEggRequest extends GetEggsRequest class GetEggRequest extends GetEggsRequest
{ {
public function resourceExists(): bool
{
$egg = $this->route()->parameter('egg');
return $egg instanceof Egg && $egg->exists;
}
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Eggs; namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetEggsRequest extends ApplicationApiRequest class GetEggsRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_EGGS;
protected int $permission = AdminAcl::READ;
} }

View file

@ -3,14 +3,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Eggs; namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
use Pterodactyl\Models\Egg; use Pterodactyl\Models\Egg;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreEggRequest extends ApplicationApiRequest class StoreEggRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_EGGS;
protected int $permission = AdminAcl::WRITE;
public function rules(array $rules = null): array public function rules(array $rules = null): array
{ {
return $rules ?? Egg::getRules(); return $rules ?? Egg::getRules();

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Locations; namespace Pterodactyl\Http\Requests\Api\Application\Locations;
use Pterodactyl\Models\Location;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class DeleteLocationRequest extends ApplicationApiRequest class DeleteLocationRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_LOCATIONS;
protected int $permission = AdminAcl::WRITE;
public function resourceExists(): bool
{
$location = $this->route()->parameter('location');
return $location instanceof Location && $location->exists;
}
} }

View file

@ -2,14 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Application\Locations; namespace Pterodactyl\Http\Requests\Api\Application\Locations;
use Pterodactyl\Models\Location;
class GetLocationRequest extends GetLocationsRequest class GetLocationRequest extends GetLocationsRequest
{ {
public function resourceExists(): bool
{
$location = $this->route()->parameter('location');
return $location instanceof Location && $location->exists;
}
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Locations; namespace Pterodactyl\Http\Requests\Api\Application\Locations;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetLocationsRequest extends ApplicationApiRequest class GetLocationsRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_LOCATIONS;
protected int $permission = AdminAcl::READ;
} }

View file

@ -3,14 +3,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Locations; namespace Pterodactyl\Http\Requests\Api\Application\Locations;
use Pterodactyl\Models\Location; use Pterodactyl\Models\Location;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreLocationRequest extends ApplicationApiRequest class StoreLocationRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_LOCATIONS;
protected int $permission = AdminAcl::WRITE;
public function rules(): array public function rules(): array
{ {
return collect(Location::getRules())->only([ return collect(Location::getRules())->only([

View file

@ -6,13 +6,6 @@ use Pterodactyl\Models\Location;
class UpdateLocationRequest extends StoreLocationRequest class UpdateLocationRequest extends StoreLocationRequest
{ {
public function resourceExists(): bool
{
$location = $this->route()->parameter('location');
return $location instanceof Location && $location->exists;
}
public function rules(): array public function rules(): array
{ {
$locationId = $this->route()->parameter('location')->id; $locationId = $this->route()->parameter('location')->id;

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Mounts; namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
use Pterodactyl\Models\Mount;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class DeleteMountRequest extends ApplicationApiRequest class DeleteMountRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_MOUNTS;
protected int $permission = AdminAcl::WRITE;
public function resourceExists(): bool
{
$mount = $this->route()->parameter('mount');
return $mount instanceof Mount && $mount->exists;
}
} }

View file

@ -2,14 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Application\Mounts; namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
use Pterodactyl\Models\Mount;
class GetMountRequest extends GetMountsRequest class GetMountRequest extends GetMountsRequest
{ {
public function resourceExists(): bool
{
$mount = $this->route()->parameter('mount');
return $mount instanceof Mount && $mount->exists;
}
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Mounts; namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
use Pterodactyl\Services\Acl\Api\AdminAcl as Acl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetMountsRequest extends ApplicationApiRequest class GetMountsRequest extends ApplicationApiRequest
{ {
protected string $resource = Acl::RESOURCE_MOUNTS;
protected int $permission = Acl::READ;
} }

View file

@ -2,14 +2,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Mounts; namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class MountEggsRequest extends ApplicationApiRequest class MountEggsRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_MOUNTS;
protected int $permission = AdminAcl::WRITE;
public function rules(array $rules = null): array public function rules(array $rules = null): array
{ {
return $rules ?? ['eggs' => 'required|exists:eggs,id']; return $rules ?? ['eggs' => 'required|exists:eggs,id'];

View file

@ -2,14 +2,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Mounts; namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class MountNodesRequest extends ApplicationApiRequest class MountNodesRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_MOUNTS;
protected int $permission = AdminAcl::WRITE;
public function rules(array $rules = null): array public function rules(array $rules = null): array
{ {
return $rules ?? ['nodes' => 'required|exists:nodes,id']; return $rules ?? ['nodes' => 'required|exists:nodes,id'];

View file

@ -3,14 +3,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Mounts; namespace Pterodactyl\Http\Requests\Api\Application\Mounts;
use Pterodactyl\Models\Mount; use Pterodactyl\Models\Mount;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreMountRequest extends ApplicationApiRequest class StoreMountRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_MOUNTS;
protected int $permission = AdminAcl::WRITE;
public function rules(array $rules = null): array public function rules(array $rules = null): array
{ {
return $rules ?? Mount::getRules(); return $rules ?? Mount::getRules();

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nests; namespace Pterodactyl\Http\Requests\Api\Application\Nests;
use Pterodactyl\Models\Nest;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class DeleteNestRequest extends ApplicationApiRequest class DeleteNestRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_NESTS;
protected int $permission = AdminAcl::WRITE;
public function resourceExists(): bool
{
$nest = $this->route()->parameter('nest');
return $nest instanceof Nest && $nest->exists;
}
} }

View file

@ -2,14 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nests; namespace Pterodactyl\Http\Requests\Api\Application\Nests;
use Pterodactyl\Models\Nest;
class GetNestRequest extends GetNestsRequest class GetNestRequest extends GetNestsRequest
{ {
public function resourceExists(): bool
{
$nest = $this->route()->parameter('nest');
return $nest instanceof Nest && $nest->exists;
}
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nests; namespace Pterodactyl\Http\Requests\Api\Application\Nests;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetNestsRequest extends ApplicationApiRequest class GetNestsRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_NESTS;
protected int $permission = AdminAcl::READ;
} }

View file

@ -2,17 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nests; namespace Pterodactyl\Http\Requests\Api\Application\Nests;
use Pterodactyl\Models\Nest;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreNestRequest extends ApplicationApiRequest class StoreNestRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_NESTS;
protected int $permission = AdminAcl::WRITE;
public function rules(array $rules = null): array
{
return $rules ?? Nest::getRules();
}
} }

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nodes; namespace Pterodactyl\Http\Requests\Api\Application\Nodes;
use Pterodactyl\Models\Node;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class DeleteNodeRequest extends ApplicationApiRequest class DeleteNodeRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_NODES;
protected int $permission = AdminAcl::WRITE;
public function resourceExists(): bool
{
$node = $this->route()->parameter('node');
return $node instanceof Node && $node->exists;
}
} }

View file

@ -2,14 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nodes; namespace Pterodactyl\Http\Requests\Api\Application\Nodes;
use Pterodactyl\Models\Node;
class GetNodeRequest extends GetNodesRequest class GetNodeRequest extends GetNodesRequest
{ {
public function resourceExists(): bool
{
$node = $this->route()->parameter('node');
return $node instanceof Node && $node->exists;
}
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nodes; namespace Pterodactyl\Http\Requests\Api\Application\Nodes;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetNodesRequest extends ApplicationApiRequest class GetNodesRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_NODES;
protected int $permission = AdminAcl::READ;
} }

View file

@ -3,14 +3,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nodes; namespace Pterodactyl\Http\Requests\Api\Application\Nodes;
use Pterodactyl\Models\Node; use Pterodactyl\Models\Node;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreNodeRequest extends ApplicationApiRequest class StoreNodeRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_NODES;
protected int $permission = AdminAcl::WRITE;
/** /**
* Validation rules to apply to this request. * Validation rules to apply to this request.
*/ */

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Roles; namespace Pterodactyl\Http\Requests\Api\Application\Roles;
use Pterodactyl\Models\AdminRole;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class DeleteRoleRequest extends ApplicationApiRequest class DeleteRoleRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_ROLES;
protected int $permission = AdminAcl::WRITE;
public function resourceExists(): bool
{
$role = $this->route()->parameter('role');
return $role instanceof AdminRole && $role->exists;
}
} }

View file

@ -2,14 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Application\Roles; namespace Pterodactyl\Http\Requests\Api\Application\Roles;
use Pterodactyl\Models\AdminRole;
class GetRoleRequest extends GetRolesRequest class GetRoleRequest extends GetRolesRequest
{ {
public function resourceExists(): bool
{
$role = $this->route()->parameter('role');
return $role instanceof AdminRole && $role->exists;
}
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Roles; namespace Pterodactyl\Http\Requests\Api\Application\Roles;
use Pterodactyl\Services\Acl\Api\AdminAcl as Acl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetRolesRequest extends ApplicationApiRequest class GetRolesRequest extends ApplicationApiRequest
{ {
protected string $resource = Acl::RESOURCE_ROLES;
protected int $permission = Acl::READ;
} }

View file

@ -3,14 +3,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Roles; namespace Pterodactyl\Http\Requests\Api\Application\Roles;
use Pterodactyl\Models\AdminRole; use Pterodactyl\Models\AdminRole;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreRoleRequest extends ApplicationApiRequest class StoreRoleRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_ROLES;
protected int $permission = AdminAcl::WRITE;
public function rules(array $rules = null): array public function rules(array $rules = null): array
{ {
return $rules ?? AdminRole::getRules(); return $rules ?? AdminRole::getRules();

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Servers\Databases; namespace Pterodactyl\Http\Requests\Api\Application\Servers\Databases;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetServerDatabaseRequest extends ApplicationApiRequest class GetServerDatabaseRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_SERVER_DATABASES;
protected int $permission = AdminAcl::READ;
public function resourceExists(): bool
{
$server = $this->route()->parameter('server');
$database = $this->route()->parameter('database');
return $database->server_id === $server->id;
}
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Servers\Databases; namespace Pterodactyl\Http\Requests\Api\Application\Servers\Databases;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetServerDatabasesRequest extends ApplicationApiRequest class GetServerDatabasesRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_SERVER_DATABASES;
protected int $permission = AdminAcl::READ;
} }

View file

@ -2,9 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Application\Servers\Databases; namespace Pterodactyl\Http\Requests\Api\Application\Servers\Databases;
use Pterodactyl\Services\Acl\Api\AdminAcl;
class ServerDatabaseWriteRequest extends GetServerDatabasesRequest class ServerDatabaseWriteRequest extends GetServerDatabasesRequest
{ {
protected int $permission = AdminAcl::WRITE;
} }

View file

@ -6,15 +6,11 @@ use Webmozart\Assert\Assert;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Illuminate\Database\Query\Builder; use Illuminate\Database\Query\Builder;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Services\Databases\DatabaseManagementService; use Pterodactyl\Services\Databases\DatabaseManagementService;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreServerDatabaseRequest extends ApplicationApiRequest class StoreServerDatabaseRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_SERVER_DATABASES;
protected int $permission = AdminAcl::WRITE;
public function rules(): array public function rules(): array
{ {
$server = $this->route()->parameter('server'); $server = $this->route()->parameter('server');

View file

@ -2,35 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Servers; namespace Pterodactyl\Http\Requests\Api\Application\Servers;
use Pterodactyl\Models\Server;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetExternalServerRequest extends ApplicationApiRequest class GetExternalServerRequest extends ApplicationApiRequest
{ {
private Server $serverModel;
protected string $resource = AdminAcl::RESOURCE_SERVERS;
protected int $permission = AdminAcl::READ;
public function resourceExists(): bool
{
$repository = $this->container->make(ServerRepositoryInterface::class);
try {
$this->serverModel = $repository->findFirstWhere([
['external_id', '=', $this->route()->parameter('external_id')],
]);
} catch (RecordNotFoundException $exception) {
return false;
}
return true;
}
public function getServerModel(): Server
{
return $this->serverModel;
}
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Servers; namespace Pterodactyl\Http\Requests\Api\Application\Servers;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetServerRequest extends ApplicationApiRequest class GetServerRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_SERVERS;
protected int $permission = AdminAcl::READ;
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Servers; namespace Pterodactyl\Http\Requests\Api\Application\Servers;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class ServerWriteRequest extends ApplicationApiRequest class ServerWriteRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_SERVERS;
protected int $permission = AdminAcl::WRITE;
} }

View file

@ -4,16 +4,12 @@ namespace Pterodactyl\Http\Requests\Api\Application\Servers;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Contracts\Validation\Validator;
use Pterodactyl\Models\Objects\DeploymentObject; use Pterodactyl\Models\Objects\DeploymentObject;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreServerRequest extends ApplicationApiRequest class StoreServerRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_SERVERS;
protected int $permission = AdminAcl::WRITE;
public function rules(): array public function rules(): array
{ {
$rules = Server::getRules(); $rules = Server::getRules();
@ -93,7 +89,9 @@ class StoreServerRequest extends ApplicationApiRequest
public function withValidator(Validator $validator) public function withValidator(Validator $validator)
{ {
$validator->sometimes('allocation.default', [ $validator->sometimes('allocation.default', [
'required', 'integer', 'bail', 'required',
'integer',
'bail',
Rule::exists('allocations', 'id')->where(function ($query) { Rule::exists('allocations', 'id')->where(function ($query) {
$query->whereNull('server_id'); $query->whereNull('server_id');
}), }),

View file

@ -3,14 +3,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Servers; namespace Pterodactyl\Http\Requests\Api\Application\Servers;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class UpdateServerStartupRequest extends ApplicationApiRequest class UpdateServerStartupRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_SERVERS;
protected int $permission = AdminAcl::WRITE;
public function rules(): array public function rules(): array
{ {
$data = Server::getRulesForUpdate($this->route()->parameter('server')->id); $data = Server::getRulesForUpdate($this->route()->parameter('server')->id);

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Users; namespace Pterodactyl\Http\Requests\Api\Application\Users;
use Pterodactyl\Models\User;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class DeleteUserRequest extends ApplicationApiRequest class DeleteUserRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_USERS;
protected int $permission = AdminAcl::WRITE;
public function resourceExists(): bool
{
$user = $this->route()->parameter('user');
return $user instanceof User && $user->exists;
}
} }

View file

@ -2,35 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Users; namespace Pterodactyl\Http\Requests\Api\Application\Users;
use Pterodactyl\Models\User;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetExternalUserRequest extends ApplicationApiRequest class GetExternalUserRequest extends ApplicationApiRequest
{ {
private User $userModel;
protected string $resource = AdminAcl::RESOURCE_USERS;
protected int $permission = AdminAcl::READ;
public function resourceExists(): bool
{
$repository = $this->container->make(UserRepositoryInterface::class);
try {
$this->userModel = $repository->findFirstWhere([
['external_id', '=', $this->route()->parameter('external_id')],
]);
} catch (RecordNotFoundException $exception) {
return false;
}
return true;
}
public function getUserModel(): User
{
return $this->userModel;
}
} }

View file

@ -2,14 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Application\Users; namespace Pterodactyl\Http\Requests\Api\Application\Users;
use Pterodactyl\Models\User;
class GetUserRequest extends GetUsersRequest class GetUserRequest extends GetUsersRequest
{ {
public function resourceExists(): bool
{
$user = $this->route()->parameter('user');
return $user instanceof User && $user->exists;
}
} }

View file

@ -2,11 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Users; namespace Pterodactyl\Http\Requests\Api\Application\Users;
use Pterodactyl\Services\Acl\Api\AdminAcl as Acl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class GetUsersRequest extends ApplicationApiRequest class GetUsersRequest extends ApplicationApiRequest
{ {
protected string $resource = Acl::RESOURCE_USERS;
protected int $permission = Acl::READ;
} }

View file

@ -3,14 +3,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Users; namespace Pterodactyl\Http\Requests\Api\Application\Users;
use Pterodactyl\Models\User; use Pterodactyl\Models\User;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest; use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreUserRequest extends ApplicationApiRequest class StoreUserRequest extends ApplicationApiRequest
{ {
protected string $resource = AdminAcl::RESOURCE_USERS;
protected int $permission = AdminAcl::WRITE;
public function rules(array $rules = null): array public function rules(array $rules = null): array
{ {
$rules = $rules ?? User::getRules(); $rules = $rules ?? User::getRules();

View file

@ -3,11 +3,17 @@
namespace Pterodactyl\Http\Requests\Api\Client; namespace Pterodactyl\Http\Requests\Api\Client;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\ApiRequest;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
abstract class ClientApiRequest extends ApplicationApiRequest implements ClientPermissionsRequest abstract class ClientApiRequest extends ApiRequest
{ {
/**
* Returns the permissions string indicating which permission should be used to
* validate that the authenticated user has permission to perform this action aganist
* the given resource (server).
*/
abstract public function permission(): string;
/** /**
* Determine if the current user is authorized to perform the requested action * Determine if the current user is authorized to perform the requested action
* against the API. * against the API.

View file

@ -4,7 +4,6 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Settings;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Pterodactyl\Models\Permission; use Pterodactyl\Models\Permission;
use Pterodactyl\Contracts\Http\ClientPermissionsRequest;
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
class RenameServerRequest extends ClientApiRequest class RenameServerRequest extends ClientApiRequest

View file

@ -1,40 +0,0 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
abstract class FrontendUserFormRequest extends FormRequest
{
abstract public function rules();
/**
* Determine if a user is authorized to access this endpoint.
*
* @return bool
*/
public function authorize()
{
return !is_null($this->user());
}
/**
* Return only the fields that we are interested in from the request.
* This will include empty fields as a null value.
*
* @return array
*/
public function normalize()
{
return $this->only(
array_keys($this->rules())
);
}
}