From 9b654d2c768feeaead6c0d1db2aac778b39da7c1 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 10 Nov 2018 15:27:50 -0800 Subject: [PATCH] Fix bug with client API denying access to routes, closes #1366 --- .../Api/Client/Servers/CommandController.php | 14 +------ .../Api/Client/Servers/PowerController.php | 14 +------ .../Api/Client/AuthenticateClientAccess.php | 37 ++++++++++++++++++- .../Api/Client/Servers/GetServerRequest.php | 11 ------ 4 files changed, 39 insertions(+), 37 deletions(-) diff --git a/app/Http/Controllers/Api/Client/Servers/CommandController.php b/app/Http/Controllers/Api/Client/Servers/CommandController.php index 8a5b951f5..881548fa0 100644 --- a/app/Http/Controllers/Api/Client/Servers/CommandController.php +++ b/app/Http/Controllers/Api/Client/Servers/CommandController.php @@ -7,7 +7,6 @@ use Pterodactyl\Models\Server; use Psr\Http\Message\ResponseInterface; use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Exception\RequestException; -use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService; use Pterodactyl\Http\Controllers\Api\Client\ClientApiController; use Pterodactyl\Http\Requests\Api\Client\Servers\SendCommandRequest; use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException; @@ -16,11 +15,6 @@ use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException; class CommandController extends ClientApiController { - /** - * @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService - */ - private $keyProviderService; - /** * @var \Pterodactyl\Contracts\Repository\Daemon\CommandRepositoryInterface */ @@ -30,13 +24,11 @@ class CommandController extends ClientApiController * CommandController constructor. * * @param \Pterodactyl\Contracts\Repository\Daemon\CommandRepositoryInterface $repository - * @param \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService $keyProviderService */ - public function __construct(CommandRepositoryInterface $repository, DaemonKeyProviderService $keyProviderService) + public function __construct(CommandRepositoryInterface $repository) { parent::__construct(); - $this->keyProviderService = $keyProviderService; $this->repository = $repository; } @@ -46,14 +38,12 @@ class CommandController extends ClientApiController * @param \Pterodactyl\Http\Requests\Api\Client\Servers\SendCommandRequest $request * @return \Illuminate\Http\Response * - * @throws \Pterodactyl\Exceptions\Model\DataValidationException - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException */ public function index(SendCommandRequest $request): Response { $server = $request->getModel(Server::class); - $token = $this->keyProviderService->handle($server, $request->user()); + $token = $request->attributes->get('server_token'); try { $this->repository->setServer($server) diff --git a/app/Http/Controllers/Api/Client/Servers/PowerController.php b/app/Http/Controllers/Api/Client/Servers/PowerController.php index 113b83398..7a96a2a4e 100644 --- a/app/Http/Controllers/Api/Client/Servers/PowerController.php +++ b/app/Http/Controllers/Api/Client/Servers/PowerController.php @@ -4,18 +4,12 @@ namespace Pterodactyl\Http\Controllers\Api\Client\Servers; use Illuminate\Http\Response; use Pterodactyl\Models\Server; -use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService; use Pterodactyl\Http\Controllers\Api\Client\ClientApiController; use Pterodactyl\Http\Requests\Api\Client\Servers\SendPowerRequest; use Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface; class PowerController extends ClientApiController { - /** - * @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService - */ - private $keyProviderService; - /** * @var \Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface */ @@ -24,14 +18,12 @@ class PowerController extends ClientApiController /** * PowerController constructor. * - * @param \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService $keyProviderService * @param \Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface $repository */ - public function __construct(DaemonKeyProviderService $keyProviderService, PowerRepositoryInterface $repository) + public function __construct(PowerRepositoryInterface $repository) { parent::__construct(); - $this->keyProviderService = $keyProviderService; $this->repository = $repository; } @@ -41,14 +33,12 @@ class PowerController extends ClientApiController * @param \Pterodactyl\Http\Requests\Api\Client\Servers\SendPowerRequest $request * @return \Illuminate\Http\Response * - * @throws \Pterodactyl\Exceptions\Model\DataValidationException - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\Daemon\InvalidPowerSignalException */ public function index(SendPowerRequest $request): Response { $server = $request->getModel(Server::class); - $token = $this->keyProviderService->handle($server, $request->user()); + $token = $request->attributes->get('server_token'); $this->repository->setServer($server)->setToken($token)->sendSignal($request->input('signal')); diff --git a/app/Http/Middleware/Api/Client/AuthenticateClientAccess.php b/app/Http/Middleware/Api/Client/AuthenticateClientAccess.php index 0a006aef0..e048b5869 100644 --- a/app/Http/Middleware/Api/Client/AuthenticateClientAccess.php +++ b/app/Http/Middleware/Api/Client/AuthenticateClientAccess.php @@ -4,24 +4,57 @@ namespace Pterodactyl\Http\Middleware\Api\Client; use Closure; use Illuminate\Http\Request; +use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService; +use Pterodactyl\Exceptions\Repository\RecordNotFoundException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; class AuthenticateClientAccess { + /** + * @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService + */ + private $keyProviderService; + + /** + * AuthenticateClientAccess constructor. + * + * @param \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService $keyProviderService + */ + public function __construct(DaemonKeyProviderService $keyProviderService) + { + $this->keyProviderService = $keyProviderService; + } + /** * Authenticate that the currently authenticated user has permission - * to access the specified server. + * to access the specified server. This only checks that the user is an + * admin, owner, or a subuser. You'll need to do more specific checks in + * the API calls to determine if they can perform different actions. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed + * + * @throws \Pterodactyl\Exceptions\Model\DataValidationException */ public function handle(Request $request, Closure $next) { if (is_null($request->user())) { - throw new AccessDeniedHttpException('This account does not have permission to access this resource.'); + throw new AccessDeniedHttpException('A request must be made using an authenticated client.'); } + /** @var \Pterodactyl\Models\Server $server */ + $server = $request->route()->parameter('server'); + + try { + $token = $this->keyProviderService->handle($server, $request->user()); + } catch (RecordNotFoundException $exception) { + throw new NotFoundHttpException('The requested server could not be located.'); + } + + $request->attributes->set('server_token', $token); + return $next($request); } } diff --git a/app/Http/Requests/Api/Client/Servers/GetServerRequest.php b/app/Http/Requests/Api/Client/Servers/GetServerRequest.php index ad2312067..b69203fc1 100644 --- a/app/Http/Requests/Api/Client/Servers/GetServerRequest.php +++ b/app/Http/Requests/Api/Client/Servers/GetServerRequest.php @@ -2,7 +2,6 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers; -use Pterodactyl\Models\Server; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; class GetServerRequest extends ClientApiRequest @@ -18,14 +17,4 @@ class GetServerRequest extends ClientApiRequest { return true; } - - /** - * Determine if the user should even know that this server exists. - * - * @return bool - */ - public function resourceExists(): bool - { - return $this->user()->can('view-server', $this->getModel(Server::class)); - } }