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;
use Pterodactyl\Models\Server;
use Pterodactyl\Transformers\Api\Application\ServerTransformer;
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
use Pterodactyl\Http\Requests\Api\Application\Servers\GetExternalServerRequest;
@ -13,9 +14,11 @@ class ExternalServerController extends ApplicationApiController
*
* @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))
->toArray();
}

View file

@ -2,6 +2,7 @@
namespace Pterodactyl\Http\Controllers\Api\Application\Users;
use Pterodactyl\Models\User;
use Pterodactyl\Transformers\Api\Application\UserTransformer;
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
use Pterodactyl\Http\Requests\Api\Application\Users\GetExternalUserRequest;
@ -13,9 +14,11 @@ class ExternalUserController extends ApplicationApiController
*
* @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))
->toArray();
}

View file

@ -74,14 +74,4 @@ class ApiSubstituteBindings extends SubstituteBindings
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;
use Pterodactyl\Models\Node;
use Pterodactyl\Models\Allocation;
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;
/**
* 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;
use Pterodactyl\Models\Node;
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;
/**
* 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;
use Pterodactyl\Services\Acl\Api\AdminAcl;
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 [

View file

@ -2,119 +2,18 @@
namespace Pterodactyl\Http\Requests\Api\Application;
use Pterodactyl\Models\ApiKey;
use Illuminate\Foundation\Http\FormRequest;
use Pterodactyl\Http\Middleware\Api\ApiSubstituteBindings;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Exception\InvalidParameterException;
use Pterodactyl\Http\Requests\Api\ApiRequest;
abstract class ApplicationApiRequest extends FormRequest
abstract class ApplicationApiRequest extends ApiRequest
{
/**
* 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.
* This will eventually be replaced with per-request permissions checking
* on the API key and for the user.
*
* @return bool
*/
public function authorize(): bool
{
return false;
}
/**
* 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;
return $this->user()->root_admin;
}
}

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Databases;
use Pterodactyl\Models\DatabaseHost;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\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;
use Pterodactyl\Models\DatabaseHost;
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;
use Pterodactyl\Services\Acl\Api\AdminAcl as Acl;
use Pterodactyl\Http\Requests\Api\Application\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;
use Pterodactyl\Models\DatabaseHost;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreDatabaseRequest extends ApplicationApiRequest
{
protected string $resource = AdminAcl::RESOURCE_DATABASE_HOSTS;
protected int $permission = AdminAcl::WRITE;
public function rules(array $rules = null): array
{
return $rules ?? DatabaseHost::getRules();

View file

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

View file

@ -2,14 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Application\Eggs;
use Pterodactyl\Models\Egg;
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;
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;
}

View file

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

View file

@ -2,19 +2,8 @@
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 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;
use Pterodactyl\Models\Location;
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;
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;
}

View file

@ -3,14 +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;
public function rules(): array
{
return collect(Location::getRules())->only([

View file

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

View file

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

View file

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

View file

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

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nests;
use Pterodactyl\Models\Nest;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\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;
use Pterodactyl\Models\Nest;
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;
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;
}

View file

@ -2,17 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nests;
use Pterodactyl\Models\Nest;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\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;
use Pterodactyl\Models\Node;
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;
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;
use Pterodactyl\Models\Node;
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;
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;
}

View file

@ -3,14 +3,10 @@
namespace Pterodactyl\Http\Requests\Api\Application\Nodes;
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.
*/

View file

@ -2,19 +2,8 @@
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
use Pterodactyl\Models\AdminRole;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\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;
use Pterodactyl\Models\AdminRole;
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;
use Pterodactyl\Services\Acl\Api\AdminAcl as Acl;
use Pterodactyl\Http\Requests\Api\Application\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;
use Pterodactyl\Models\AdminRole;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
class StoreRoleRequest extends ApplicationApiRequest
{
protected string $resource = AdminAcl::RESOURCE_ROLES;
protected int $permission = AdminAcl::WRITE;
public function rules(array $rules = null): array
{
return $rules ?? AdminRole::getRules();

View file

@ -2,19 +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;
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;
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;
}

View file

@ -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;
}

View file

@ -6,15 +6,11 @@ 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;
public function rules(): array
{
$server = $this->route()->parameter('server');

View file

@ -2,35 +2,8 @@
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;
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;
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;
}

View file

@ -2,11 +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;
}

View file

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

View file

@ -3,14 +3,10 @@
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;
public function rules(): array
{
$data = Server::getRulesForUpdate($this->route()->parameter('server')->id);

View file

@ -2,19 +2,8 @@
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 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;
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;
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;
use Pterodactyl\Models\User;
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;
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;
}

View file

@ -3,14 +3,10 @@
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;
public function rules(array $rules = null): array
{
$rules = $rules ?? User::getRules();

View file

@ -3,11 +3,17 @@
namespace Pterodactyl\Http\Requests\Api\Client;
use Pterodactyl\Models\Server;
use Pterodactyl\Contracts\Http\ClientPermissionsRequest;
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
use Pterodactyl\Http\Requests\Api\ApiRequest;
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
* against the API.

View file

@ -4,7 +4,6 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Settings;
use Pterodactyl\Models\Server;
use Pterodactyl\Models\Permission;
use Pterodactyl\Contracts\Http\ClientPermissionsRequest;
use Pterodactyl\Http\Requests\Api\Client\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())
);
}
}