From c521d37ddd82ddedee90aae3eee5f3c119d9fccb Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Tue, 23 Mar 2021 15:57:29 -0600 Subject: [PATCH] api(app): more consistent handling of per_page query param --- .../QueryValueOutOfRangeHttpException.php | 21 +++++++++++++++++++ .../Databases/DatabaseController.php | 8 +++---- .../Api/Application/Eggs/EggController.php | 18 ++++++++++++---- .../Locations/LocationController.php | 8 +++---- .../Application/Mounts/MountController.php | 8 +++---- .../Api/Application/Nests/NestController.php | 18 +++++++++------- .../Nodes/AllocationController.php | 8 ++++++- .../Api/Application/Nodes/NodeController.php | 8 +++---- .../Application/Servers/ServerController.php | 8 +++---- .../Api/Application/Users/UserController.php | 8 +++---- 10 files changed, 71 insertions(+), 42 deletions(-) create mode 100644 app/Exceptions/Http/QueryValueOutOfRangeHttpException.php diff --git a/app/Exceptions/Http/QueryValueOutOfRangeHttpException.php b/app/Exceptions/Http/QueryValueOutOfRangeHttpException.php new file mode 100644 index 000000000..4610f0e2e --- /dev/null +++ b/app/Exceptions/Http/QueryValueOutOfRangeHttpException.php @@ -0,0 +1,21 @@ +query('per_page', 10); - if ($perPage < 1) { - $perPage = 10; - } elseif ($perPage > 100) { - throw new BadRequestHttpException('"per_page" query parameter must be below 100.'); + if ($perPage < 1 || $perPage > 100) { + throw new QueryValueOutOfRangeHttpException('per_page', 1, 100); } $databases = QueryBuilder::for(DatabaseHost::query()) diff --git a/app/Http/Controllers/Api/Application/Eggs/EggController.php b/app/Http/Controllers/Api/Application/Eggs/EggController.php index e163a5a05..11e9de273 100644 --- a/app/Http/Controllers/Api/Application/Eggs/EggController.php +++ b/app/Http/Controllers/Api/Application/Eggs/EggController.php @@ -6,13 +6,15 @@ use Pterodactyl\Models\Egg; use Pterodactyl\Models\Nest; use Illuminate\Http\Response; use Illuminate\Http\JsonResponse; +use Spatie\QueryBuilder\QueryBuilder; use Pterodactyl\Contracts\Repository\EggRepositoryInterface; use Pterodactyl\Transformers\Api\Application\EggTransformer; 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\StoreEggRequest; -use Pterodactyl\Http\Requests\Api\Application\Eggs\UpdateEggRequest; use Pterodactyl\Http\Requests\Api\Application\Eggs\DeleteEggRequest; +use Pterodactyl\Http\Requests\Api\Application\Eggs\UpdateEggRequest; use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController; class EggController extends ApplicationApiController @@ -36,9 +38,17 @@ class EggController extends ApplicationApiController */ public function index(GetEggsRequest $request, Nest $nest): array { - $eggs = $this->repository->findWhere([ - ['nest_id', '=', $nest->id], - ]); + $perPage = $request->query('per_page', 0); + 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) ->transformWith($this->getTransformer(EggTransformer::class)) diff --git a/app/Http/Controllers/Api/Application/Locations/LocationController.php b/app/Http/Controllers/Api/Application/Locations/LocationController.php index ec866ae9a..326227168 100644 --- a/app/Http/Controllers/Api/Application/Locations/LocationController.php +++ b/app/Http/Controllers/Api/Application/Locations/LocationController.php @@ -11,7 +11,7 @@ use Pterodactyl\Services\Locations\LocationCreationService; use Pterodactyl\Services\Locations\LocationDeletionService; use Pterodactyl\Contracts\Repository\LocationRepositoryInterface; 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\Requests\Api\Application\Locations\GetLocationRequest; use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationsRequest; @@ -51,10 +51,8 @@ class LocationController extends ApplicationApiController public function index(GetLocationsRequest $request): array { $perPage = $request->query('per_page', 10); - if ($perPage < 1) { - $perPage = 10; - } elseif ($perPage > 100) { - throw new BadRequestHttpException('"per_page" query parameter must be below 100.'); + if ($perPage < 1 || $perPage > 100) { + throw new QueryValueOutOfRangeHttpException('per_page', 1, 100); } $locations = QueryBuilder::for(Location::query()) diff --git a/app/Http/Controllers/Api/Application/Mounts/MountController.php b/app/Http/Controllers/Api/Application/Mounts/MountController.php index a8a0b9d54..0d860550b 100644 --- a/app/Http/Controllers/Api/Application/Mounts/MountController.php +++ b/app/Http/Controllers/Api/Application/Mounts/MountController.php @@ -7,7 +7,7 @@ use Illuminate\Http\Response; use Illuminate\Http\JsonResponse; use Spatie\QueryBuilder\QueryBuilder; 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\GetMountsRequest; use Pterodactyl\Http\Requests\Api\Application\Mounts\MountEggsRequest; @@ -35,10 +35,8 @@ class MountController extends ApplicationApiController public function index(GetMountsRequest $request): array { $perPage = $request->query('per_page', 10); - if ($perPage < 1) { - $perPage = 10; - } elseif ($perPage > 100) { - throw new BadRequestHttpException('"per_page" query parameter must be below 100.'); + if ($perPage < 1 || $perPage > 100) { + throw new QueryValueOutOfRangeHttpException('per_page', 1, 100); } $mounts = QueryBuilder::for(Mount::query()) diff --git a/app/Http/Controllers/Api/Application/Nests/NestController.php b/app/Http/Controllers/Api/Application/Nests/NestController.php index 64569bb23..9fbb5984a 100644 --- a/app/Http/Controllers/Api/Application/Nests/NestController.php +++ b/app/Http/Controllers/Api/Application/Nests/NestController.php @@ -4,13 +4,14 @@ namespace Pterodactyl\Http\Controllers\Api\Application\Nests; use Pterodactyl\Models\Nest; use Illuminate\Http\Response; +use Spatie\QueryBuilder\QueryBuilder; use Pterodactyl\Services\Nests\NestUpdateService; use Pterodactyl\Services\Nests\NestCreationService; use Pterodactyl\Services\Nests\NestDeletionService; use Pterodactyl\Contracts\Repository\NestRepositoryInterface; use Pterodactyl\Transformers\Api\Application\NestTransformer; +use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException; 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\StoreNestRequest; use Pterodactyl\Http\Requests\Api\Application\Nests\DeleteNestRequest; @@ -49,14 +50,17 @@ class NestController extends ApplicationApiController */ public function index(GetNestsRequest $request): array { - $perPage = $request->query('per_page', 10); - if ($perPage < 1) { - $perPage = 10; - } elseif ($perPage > 100) { - throw new BadRequestHttpException('"per_page" query parameter must be below 100.'); + $perPage = $request->query('per_page', 0); + if ($perPage > 100) { + throw new QueryValueOutOfRangeHttpException('per_page', 1, 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) ->transformWith($this->getTransformer(NestTransformer::class)) diff --git a/app/Http/Controllers/Api/Application/Nodes/AllocationController.php b/app/Http/Controllers/Api/Application/Nodes/AllocationController.php index 292b45b1b..d993e278b 100644 --- a/app/Http/Controllers/Api/Application/Nodes/AllocationController.php +++ b/app/Http/Controllers/Api/Application/Nodes/AllocationController.php @@ -7,6 +7,7 @@ use Illuminate\Http\Response; use Pterodactyl\Models\Allocation; use Pterodactyl\Services\Allocations\AssignmentService; use Pterodactyl\Services\Allocations\AllocationDeletionService; +use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException; use Pterodactyl\Transformers\Api\Application\AllocationTransformer; use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController; use Pterodactyl\Http\Requests\Api\Application\Allocations\GetAllocationsRequest; @@ -38,7 +39,12 @@ class AllocationController extends ApplicationApiController */ 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) ->transformWith($this->getTransformer(AllocationTransformer::class)) diff --git a/app/Http/Controllers/Api/Application/Nodes/NodeController.php b/app/Http/Controllers/Api/Application/Nodes/NodeController.php index 1bd2f7f38..549ccbf56 100644 --- a/app/Http/Controllers/Api/Application/Nodes/NodeController.php +++ b/app/Http/Controllers/Api/Application/Nodes/NodeController.php @@ -11,8 +11,8 @@ use Pterodactyl\Services\Nodes\NodeCreationService; use Pterodactyl\Services\Nodes\NodeDeletionService; use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; use Pterodactyl\Transformers\Api\Application\NodeTransformer; +use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException; 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\StoreNodeRequest; use Pterodactyl\Http\Requests\Api\Application\Nodes\DeleteNodeRequest; @@ -51,10 +51,8 @@ class NodeController extends ApplicationApiController public function index(GetNodesRequest $request): array { $perPage = $request->query('per_page', 10); - if ($perPage < 1) { - $perPage = 10; - } elseif ($perPage > 100) { - throw new BadRequestHttpException('"per_page" query parameter must be below 100.'); + if ($perPage < 1 || $perPage > 100) { + throw new QueryValueOutOfRangeHttpException('per_page', 1, 100); } $nodes = QueryBuilder::for(Node::query()) diff --git a/app/Http/Controllers/Api/Application/Servers/ServerController.php b/app/Http/Controllers/Api/Application/Servers/ServerController.php index aacb25296..832434cb3 100644 --- a/app/Http/Controllers/Api/Application/Servers/ServerController.php +++ b/app/Http/Controllers/Api/Application/Servers/ServerController.php @@ -9,7 +9,7 @@ use Spatie\QueryBuilder\QueryBuilder; use Pterodactyl\Services\Servers\ServerCreationService; use Pterodactyl\Services\Servers\ServerDeletionService; 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\GetServersRequest; use Pterodactyl\Http\Requests\Api\Application\Servers\ServerWriteRequest; @@ -42,10 +42,8 @@ class ServerController extends ApplicationApiController public function index(GetServersRequest $request): array { $perPage = $request->query('per_page', 10); - if ($perPage < 1) { - $perPage = 10; - } elseif ($perPage > 100) { - throw new BadRequestHttpException('"per_page" query parameter must be below 100.'); + if ($perPage < 1 || $perPage > 100) { + throw new QueryValueOutOfRangeHttpException('per_page', 1, 100); } $servers = QueryBuilder::for(Server::query()) diff --git a/app/Http/Controllers/Api/Application/Users/UserController.php b/app/Http/Controllers/Api/Application/Users/UserController.php index a0df1f52d..71a7fc948 100644 --- a/app/Http/Controllers/Api/Application/Users/UserController.php +++ b/app/Http/Controllers/Api/Application/Users/UserController.php @@ -11,7 +11,7 @@ use Pterodactyl\Services\Users\UserCreationService; use Pterodactyl\Services\Users\UserDeletionService; use Pterodactyl\Contracts\Repository\UserRepositoryInterface; 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\GetUsersRequest; use Pterodactyl\Http\Requests\Api\Application\Users\StoreUserRequest; @@ -53,10 +53,8 @@ class UserController extends ApplicationApiController public function index(GetUsersRequest $request): array { $perPage = $request->query('per_page', 10); - if ($perPage < 1) { - $perPage = 10; - } elseif ($perPage > 100) { - throw new BadRequestHttpException('"per_page" query parameter must be below 100.'); + if ($perPage < 1 || $perPage > 100) { + throw new QueryValueOutOfRangeHttpException('per_page', 1, 100); } $users = QueryBuilder::for(User::query())