api(app): more consistent handling of per_page query param

This commit is contained in:
Matthew Penner 2021-03-23 15:57:29 -06:00
parent 49de31bf4c
commit c521d37ddd
10 changed files with 71 additions and 42 deletions

View file

@ -0,0 +1,21 @@
<?php
namespace Pterodactyl\Exceptions\Http;
use Illuminate\Http\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class QueryValueOutOfRangeHttpException extends HttpException
{
/**
* QueryValueOutOfRangeHttpException constructor.
*/
public function __construct(string $name, int $min, int $max, \Throwable $previous = null)
{
parent::__construct(
Response::HTTP_BAD_REQUEST,
'\"' . $name . '\" query parameter must be between ' . $min . ' and ' . $max,
$previous,
);
}
}

View file

@ -8,7 +8,7 @@ use Pterodactyl\Models\DatabaseHost;
use Spatie\QueryBuilder\QueryBuilder; use Spatie\QueryBuilder\QueryBuilder;
use Pterodactyl\Services\Databases\Hosts\HostUpdateService; use Pterodactyl\Services\Databases\Hosts\HostUpdateService;
use Pterodactyl\Services\Databases\Hosts\HostCreationService; use Pterodactyl\Services\Databases\Hosts\HostCreationService;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
use Pterodactyl\Transformers\Api\Application\DatabaseHostTransformer; use Pterodactyl\Transformers\Api\Application\DatabaseHostTransformer;
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController; use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
use Pterodactyl\Http\Requests\Api\Application\Databases\GetDatabaseRequest; use Pterodactyl\Http\Requests\Api\Application\Databases\GetDatabaseRequest;
@ -41,10 +41,8 @@ class DatabaseController extends ApplicationApiController
public function index(GetDatabasesRequest $request): array public function index(GetDatabasesRequest $request): array
{ {
$perPage = $request->query('per_page', 10); $perPage = $request->query('per_page', 10);
if ($perPage < 1) { if ($perPage < 1 || $perPage > 100) {
$perPage = 10; throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
} elseif ($perPage > 100) {
throw new BadRequestHttpException('"per_page" query parameter must be below 100.');
} }
$databases = QueryBuilder::for(DatabaseHost::query()) $databases = QueryBuilder::for(DatabaseHost::query())

View file

@ -6,13 +6,15 @@ use Pterodactyl\Models\Egg;
use Pterodactyl\Models\Nest; use Pterodactyl\Models\Nest;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Spatie\QueryBuilder\QueryBuilder;
use Pterodactyl\Contracts\Repository\EggRepositoryInterface; use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
use Pterodactyl\Transformers\Api\Application\EggTransformer; use Pterodactyl\Transformers\Api\Application\EggTransformer;
use Pterodactyl\Http\Requests\Api\Application\Eggs\GetEggRequest; use Pterodactyl\Http\Requests\Api\Application\Eggs\GetEggRequest;
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
use Pterodactyl\Http\Requests\Api\Application\Eggs\GetEggsRequest; use Pterodactyl\Http\Requests\Api\Application\Eggs\GetEggsRequest;
use Pterodactyl\Http\Requests\Api\Application\Eggs\StoreEggRequest; use Pterodactyl\Http\Requests\Api\Application\Eggs\StoreEggRequest;
use Pterodactyl\Http\Requests\Api\Application\Eggs\UpdateEggRequest;
use Pterodactyl\Http\Requests\Api\Application\Eggs\DeleteEggRequest; use Pterodactyl\Http\Requests\Api\Application\Eggs\DeleteEggRequest;
use Pterodactyl\Http\Requests\Api\Application\Eggs\UpdateEggRequest;
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController; use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
class EggController extends ApplicationApiController class EggController extends ApplicationApiController
@ -36,9 +38,17 @@ class EggController extends ApplicationApiController
*/ */
public function index(GetEggsRequest $request, Nest $nest): array public function index(GetEggsRequest $request, Nest $nest): array
{ {
$eggs = $this->repository->findWhere([ $perPage = $request->query('per_page', 0);
['nest_id', '=', $nest->id], if ($perPage > 100) {
]); throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
}
$eggs = QueryBuilder::for(Egg::query())
->allowedFilters(['id', 'name', 'author'])
->allowedSorts(['id', 'name', 'author']);
if ($perPage > 0) {
$eggs = $eggs->paginate($perPage);
}
return $this->fractal->collection($eggs) return $this->fractal->collection($eggs)
->transformWith($this->getTransformer(EggTransformer::class)) ->transformWith($this->getTransformer(EggTransformer::class))

View file

@ -11,7 +11,7 @@ use Pterodactyl\Services\Locations\LocationCreationService;
use Pterodactyl\Services\Locations\LocationDeletionService; use Pterodactyl\Services\Locations\LocationDeletionService;
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface; use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
use Pterodactyl\Transformers\Api\Application\LocationTransformer; use Pterodactyl\Transformers\Api\Application\LocationTransformer;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController; use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationRequest; use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationRequest;
use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationsRequest; use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationsRequest;
@ -51,10 +51,8 @@ class LocationController extends ApplicationApiController
public function index(GetLocationsRequest $request): array public function index(GetLocationsRequest $request): array
{ {
$perPage = $request->query('per_page', 10); $perPage = $request->query('per_page', 10);
if ($perPage < 1) { if ($perPage < 1 || $perPage > 100) {
$perPage = 10; throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
} elseif ($perPage > 100) {
throw new BadRequestHttpException('"per_page" query parameter must be below 100.');
} }
$locations = QueryBuilder::for(Location::query()) $locations = QueryBuilder::for(Location::query())

View file

@ -7,7 +7,7 @@ use Illuminate\Http\Response;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Spatie\QueryBuilder\QueryBuilder; use Spatie\QueryBuilder\QueryBuilder;
use Pterodactyl\Transformers\Api\Application\MountTransformer; use Pterodactyl\Transformers\Api\Application\MountTransformer;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
use Pterodactyl\Http\Requests\Api\Application\Mounts\GetMountRequest; use Pterodactyl\Http\Requests\Api\Application\Mounts\GetMountRequest;
use Pterodactyl\Http\Requests\Api\Application\Mounts\GetMountsRequest; use Pterodactyl\Http\Requests\Api\Application\Mounts\GetMountsRequest;
use Pterodactyl\Http\Requests\Api\Application\Mounts\MountEggsRequest; use Pterodactyl\Http\Requests\Api\Application\Mounts\MountEggsRequest;
@ -35,10 +35,8 @@ class MountController extends ApplicationApiController
public function index(GetMountsRequest $request): array public function index(GetMountsRequest $request): array
{ {
$perPage = $request->query('per_page', 10); $perPage = $request->query('per_page', 10);
if ($perPage < 1) { if ($perPage < 1 || $perPage > 100) {
$perPage = 10; throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
} elseif ($perPage > 100) {
throw new BadRequestHttpException('"per_page" query parameter must be below 100.');
} }
$mounts = QueryBuilder::for(Mount::query()) $mounts = QueryBuilder::for(Mount::query())

View file

@ -4,13 +4,14 @@ namespace Pterodactyl\Http\Controllers\Api\Application\Nests;
use Pterodactyl\Models\Nest; use Pterodactyl\Models\Nest;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Spatie\QueryBuilder\QueryBuilder;
use Pterodactyl\Services\Nests\NestUpdateService; use Pterodactyl\Services\Nests\NestUpdateService;
use Pterodactyl\Services\Nests\NestCreationService; use Pterodactyl\Services\Nests\NestCreationService;
use Pterodactyl\Services\Nests\NestDeletionService; use Pterodactyl\Services\Nests\NestDeletionService;
use Pterodactyl\Contracts\Repository\NestRepositoryInterface; use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
use Pterodactyl\Transformers\Api\Application\NestTransformer; use Pterodactyl\Transformers\Api\Application\NestTransformer;
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
use Pterodactyl\Http\Requests\Api\Application\Nests\GetNestRequest; use Pterodactyl\Http\Requests\Api\Application\Nests\GetNestRequest;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Pterodactyl\Http\Requests\Api\Application\Nests\GetNestsRequest; use Pterodactyl\Http\Requests\Api\Application\Nests\GetNestsRequest;
use Pterodactyl\Http\Requests\Api\Application\Nests\StoreNestRequest; use Pterodactyl\Http\Requests\Api\Application\Nests\StoreNestRequest;
use Pterodactyl\Http\Requests\Api\Application\Nests\DeleteNestRequest; use Pterodactyl\Http\Requests\Api\Application\Nests\DeleteNestRequest;
@ -49,14 +50,17 @@ class NestController extends ApplicationApiController
*/ */
public function index(GetNestsRequest $request): array public function index(GetNestsRequest $request): array
{ {
$perPage = $request->query('per_page', 10); $perPage = $request->query('per_page', 0);
if ($perPage < 1) { if ($perPage > 100) {
$perPage = 10; throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
} elseif ($perPage > 100) {
throw new BadRequestHttpException('"per_page" query parameter must be below 100.');
} }
$nests = $this->repository->paginated($perPage); $nests = QueryBuilder::for(Nest::query())
->allowedFilters(['id', 'name', 'author'])
->allowedSorts(['id', 'name', 'author']);
if ($perPage > 0) {
$nests = $nests->paginate($perPage);
}
return $this->fractal->collection($nests) return $this->fractal->collection($nests)
->transformWith($this->getTransformer(NestTransformer::class)) ->transformWith($this->getTransformer(NestTransformer::class))

View file

@ -7,6 +7,7 @@ use Illuminate\Http\Response;
use Pterodactyl\Models\Allocation; use Pterodactyl\Models\Allocation;
use Pterodactyl\Services\Allocations\AssignmentService; use Pterodactyl\Services\Allocations\AssignmentService;
use Pterodactyl\Services\Allocations\AllocationDeletionService; use Pterodactyl\Services\Allocations\AllocationDeletionService;
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
use Pterodactyl\Transformers\Api\Application\AllocationTransformer; use Pterodactyl\Transformers\Api\Application\AllocationTransformer;
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController; use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
use Pterodactyl\Http\Requests\Api\Application\Allocations\GetAllocationsRequest; use Pterodactyl\Http\Requests\Api\Application\Allocations\GetAllocationsRequest;
@ -38,7 +39,12 @@ class AllocationController extends ApplicationApiController
*/ */
public function index(GetAllocationsRequest $request, Node $node): array public function index(GetAllocationsRequest $request, Node $node): array
{ {
$allocations = $node->allocations()->paginate(50); $perPage = $request->query('per_page', 10);
if ($perPage < 1 || $perPage > 100) {
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
}
$allocations = $node->allocations()->paginate($perPage);
return $this->fractal->collection($allocations) return $this->fractal->collection($allocations)
->transformWith($this->getTransformer(AllocationTransformer::class)) ->transformWith($this->getTransformer(AllocationTransformer::class))

View file

@ -11,8 +11,8 @@ use Pterodactyl\Services\Nodes\NodeCreationService;
use Pterodactyl\Services\Nodes\NodeDeletionService; use Pterodactyl\Services\Nodes\NodeDeletionService;
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
use Pterodactyl\Transformers\Api\Application\NodeTransformer; use Pterodactyl\Transformers\Api\Application\NodeTransformer;
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
use Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodeRequest; use Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodeRequest;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodesRequest; use Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodesRequest;
use Pterodactyl\Http\Requests\Api\Application\Nodes\StoreNodeRequest; use Pterodactyl\Http\Requests\Api\Application\Nodes\StoreNodeRequest;
use Pterodactyl\Http\Requests\Api\Application\Nodes\DeleteNodeRequest; use Pterodactyl\Http\Requests\Api\Application\Nodes\DeleteNodeRequest;
@ -51,10 +51,8 @@ class NodeController extends ApplicationApiController
public function index(GetNodesRequest $request): array public function index(GetNodesRequest $request): array
{ {
$perPage = $request->query('per_page', 10); $perPage = $request->query('per_page', 10);
if ($perPage < 1) { if ($perPage < 1 || $perPage > 100) {
$perPage = 10; throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
} elseif ($perPage > 100) {
throw new BadRequestHttpException('"per_page" query parameter must be below 100.');
} }
$nodes = QueryBuilder::for(Node::query()) $nodes = QueryBuilder::for(Node::query())

View file

@ -9,7 +9,7 @@ use Spatie\QueryBuilder\QueryBuilder;
use Pterodactyl\Services\Servers\ServerCreationService; use Pterodactyl\Services\Servers\ServerCreationService;
use Pterodactyl\Services\Servers\ServerDeletionService; use Pterodactyl\Services\Servers\ServerDeletionService;
use Pterodactyl\Transformers\Api\Application\ServerTransformer; use Pterodactyl\Transformers\Api\Application\ServerTransformer;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
use Pterodactyl\Http\Requests\Api\Application\Servers\GetServerRequest; use Pterodactyl\Http\Requests\Api\Application\Servers\GetServerRequest;
use Pterodactyl\Http\Requests\Api\Application\Servers\GetServersRequest; use Pterodactyl\Http\Requests\Api\Application\Servers\GetServersRequest;
use Pterodactyl\Http\Requests\Api\Application\Servers\ServerWriteRequest; use Pterodactyl\Http\Requests\Api\Application\Servers\ServerWriteRequest;
@ -42,10 +42,8 @@ class ServerController extends ApplicationApiController
public function index(GetServersRequest $request): array public function index(GetServersRequest $request): array
{ {
$perPage = $request->query('per_page', 10); $perPage = $request->query('per_page', 10);
if ($perPage < 1) { if ($perPage < 1 || $perPage > 100) {
$perPage = 10; throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
} elseif ($perPage > 100) {
throw new BadRequestHttpException('"per_page" query parameter must be below 100.');
} }
$servers = QueryBuilder::for(Server::query()) $servers = QueryBuilder::for(Server::query())

View file

@ -11,7 +11,7 @@ use Pterodactyl\Services\Users\UserCreationService;
use Pterodactyl\Services\Users\UserDeletionService; use Pterodactyl\Services\Users\UserDeletionService;
use Pterodactyl\Contracts\Repository\UserRepositoryInterface; use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
use Pterodactyl\Transformers\Api\Application\UserTransformer; use Pterodactyl\Transformers\Api\Application\UserTransformer;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
use Pterodactyl\Http\Requests\Api\Application\Users\GetUserRequest; use Pterodactyl\Http\Requests\Api\Application\Users\GetUserRequest;
use Pterodactyl\Http\Requests\Api\Application\Users\GetUsersRequest; use Pterodactyl\Http\Requests\Api\Application\Users\GetUsersRequest;
use Pterodactyl\Http\Requests\Api\Application\Users\StoreUserRequest; use Pterodactyl\Http\Requests\Api\Application\Users\StoreUserRequest;
@ -53,10 +53,8 @@ class UserController extends ApplicationApiController
public function index(GetUsersRequest $request): array public function index(GetUsersRequest $request): array
{ {
$perPage = $request->query('per_page', 10); $perPage = $request->query('per_page', 10);
if ($perPage < 1) { if ($perPage < 1 || $perPage > 100) {
$perPage = 10; throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
} elseif ($perPage > 100) {
throw new BadRequestHttpException('"per_page" query parameter must be below 100.');
} }
$users = QueryBuilder::for(User::query()) $users = QueryBuilder::for(User::query())