From e28973bcaedc43840c44fba409d3b30a3547b341 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 25 Feb 2018 15:30:56 -0600 Subject: [PATCH] Move everything around as needed to get things setup for the client API --- .../InvalidTransformerLevelException.php | 9 ++++ .../Application/ApplicationApiController.php | 10 ++++- .../Api/Client/ClientApiController.php | 30 +++++++++++++ .../Api/Client/ClientController.php | 9 ++++ app/Http/Kernel.php | 23 +++++++--- ...er.php => AuthenticateApplicationUser.php} | 2 +- .../AuthenticateIPAccess.php | 2 +- .../Api/{Application => }/AuthenticateKey.php | 7 +-- .../Api/Client/AuthenticateClientAccess.php | 27 ++++++++++++ .../{Application => }/SetSessionDriver.php | 2 +- app/Providers/RouteServiceProvider.php | 4 ++ .../Api/Application/BaseTransformer.php | 9 +++- .../Api/Application/ServerTransformer.php | 2 + .../Api/Client/BaseClientTransformer.php | 44 +++++++++++++++++++ routes/api-client.php | 28 ++++++++++++ routes/api.php | 27 ------------ .../Api/Application/AuthenticateUserTest.php | 10 ++--- 17 files changed, 199 insertions(+), 46 deletions(-) create mode 100644 app/Exceptions/Transformer/InvalidTransformerLevelException.php create mode 100644 app/Http/Controllers/Api/Client/ClientApiController.php create mode 100644 app/Http/Controllers/Api/Client/ClientController.php rename app/Http/Middleware/Api/Application/{AuthenticateUser.php => AuthenticateApplicationUser.php} (95%) rename app/Http/Middleware/Api/{Application => }/AuthenticateIPAccess.php (95%) rename app/Http/Middleware/Api/{Application => }/AuthenticateKey.php (92%) create mode 100644 app/Http/Middleware/Api/Client/AuthenticateClientAccess.php rename app/Http/Middleware/Api/{Application => }/SetSessionDriver.php (95%) create mode 100644 app/Transformers/Api/Client/BaseClientTransformer.php create mode 100644 routes/api-client.php delete mode 100644 routes/api.php diff --git a/app/Exceptions/Transformer/InvalidTransformerLevelException.php b/app/Exceptions/Transformer/InvalidTransformerLevelException.php new file mode 100644 index 000000000..3d4c24248 --- /dev/null +++ b/app/Exceptions/Transformer/InvalidTransformerLevelException.php @@ -0,0 +1,9 @@ +make($abstract); $transformer->setKey($this->request->attributes->get('api_key')); + if (! $transformer instanceof BaseTransformer) { + throw new InvalidTransformerLevelException('Calls to ' . __METHOD__ . ' must return a transformer that is an instance of ' . __CLASS__); + } + return $transformer; } diff --git a/app/Http/Controllers/Api/Client/ClientApiController.php b/app/Http/Controllers/Api/Client/ClientApiController.php new file mode 100644 index 000000000..2ade63dff --- /dev/null +++ b/app/Http/Controllers/Api/Client/ClientApiController.php @@ -0,0 +1,30 @@ +make($abstract); + $transformer->setKey($this->request->attributes->get('api_key')); + + if (! $transformer instanceof self) { + throw new InvalidTransformerLevelException('Calls to ' . __METHOD__ . ' must return a transformer that is an instance of ' . __CLASS__); + } + + return $transformer; + } +} diff --git a/app/Http/Controllers/Api/Client/ClientController.php b/app/Http/Controllers/Api/Client/ClientController.php new file mode 100644 index 000000000..87a5e5f15 --- /dev/null +++ b/app/Http/Controllers/Api/Client/ClientController.php @@ -0,0 +1,9 @@ + [ + 'throttle:60,1', + ApiSubstituteBindings::class, + SetSessionDriver::class, + 'api..key:' . ApiKey::TYPE_ACCOUNT, AuthenticateIPAccess::class, ], 'daemon' => [ @@ -107,5 +115,8 @@ class Kernel extends HttpKernel 'server..database' => DatabaseBelongsToServer::class, 'server..subuser' => SubuserBelongsToServer::class, 'server..schedule' => ScheduleBelongsToServer::class, + + // API Specific Middleware + 'api..key' => AuthenticateKey::class, ]; } diff --git a/app/Http/Middleware/Api/Application/AuthenticateUser.php b/app/Http/Middleware/Api/Application/AuthenticateApplicationUser.php similarity index 95% rename from app/Http/Middleware/Api/Application/AuthenticateUser.php rename to app/Http/Middleware/Api/Application/AuthenticateApplicationUser.php index 7208dbaf9..48da8a74d 100644 --- a/app/Http/Middleware/Api/Application/AuthenticateUser.php +++ b/app/Http/Middleware/Api/Application/AuthenticateApplicationUser.php @@ -6,7 +6,7 @@ use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; -class AuthenticateUser +class AuthenticateApplicationUser { /** * Authenticate that the currently authenticated user is an administrator diff --git a/app/Http/Middleware/Api/Application/AuthenticateIPAccess.php b/app/Http/Middleware/Api/AuthenticateIPAccess.php similarity index 95% rename from app/Http/Middleware/Api/Application/AuthenticateIPAccess.php rename to app/Http/Middleware/Api/AuthenticateIPAccess.php index 6988c637d..4815063d5 100644 --- a/app/Http/Middleware/Api/Application/AuthenticateIPAccess.php +++ b/app/Http/Middleware/Api/AuthenticateIPAccess.php @@ -1,6 +1,6 @@ bearerToken())) { throw new HttpException(401, null, null, ['WWW-Authenticate' => 'Bearer']); @@ -68,7 +69,7 @@ class AuthenticateKey try { $model = $this->repository->findFirstWhere([ ['identifier', '=', $identifier], - ['key_type', '=', ApiKey::TYPE_APPLICATION], + ['key_type', '=', $keyType], ]); } catch (RecordNotFoundException $exception) { throw new AccessDeniedHttpException; diff --git a/app/Http/Middleware/Api/Client/AuthenticateClientAccess.php b/app/Http/Middleware/Api/Client/AuthenticateClientAccess.php new file mode 100644 index 000000000..0a006aef0 --- /dev/null +++ b/app/Http/Middleware/Api/Client/AuthenticateClientAccess.php @@ -0,0 +1,27 @@ +user())) { + throw new AccessDeniedHttpException('This account does not have permission to access this resource.'); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/Api/Application/SetSessionDriver.php b/app/Http/Middleware/Api/SetSessionDriver.php similarity index 95% rename from app/Http/Middleware/Api/Application/SetSessionDriver.php rename to app/Http/Middleware/Api/SetSessionDriver.php index c4660ec9b..c69311a65 100644 --- a/app/Http/Middleware/Api/Application/SetSessionDriver.php +++ b/app/Http/Middleware/Api/SetSessionDriver.php @@ -1,6 +1,6 @@ namespace($this->namespace . '\Api\Application') ->group(base_path('routes/api-application.php')); + Route::middleware(['client-api'])->prefix('/api/client') + ->namespace($this->namespace . '\Api\Client') + ->group(base_path('routes/api-client.php')); + Route::middleware(['daemon'])->prefix('/api/remote') ->namespace($this->namespace . '\Api\Remote') ->group(base_path('routes/api-remote.php')); diff --git a/app/Transformers/Api/Application/BaseTransformer.php b/app/Transformers/Api/Application/BaseTransformer.php index c2fdf6137..5766088c9 100644 --- a/app/Transformers/Api/Application/BaseTransformer.php +++ b/app/Transformers/Api/Application/BaseTransformer.php @@ -7,6 +7,7 @@ use Pterodactyl\Models\ApiKey; use Illuminate\Container\Container; use League\Fractal\TransformerAbstract; use Pterodactyl\Services\Acl\Api\AdminAcl; +use Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException; abstract class BaseTransformer extends TransformerAbstract { @@ -78,13 +79,19 @@ abstract class BaseTransformer extends TransformerAbstract * @param string $abstract * @param array $parameters * @return \Pterodactyl\Transformers\Api\Application\BaseTransformer + * + * @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException */ - protected function makeTransformer(string $abstract, array $parameters = []): self + protected function makeTransformer(string $abstract, array $parameters = []) { /** @var \Pterodactyl\Transformers\Api\Application\BaseTransformer $transformer */ $transformer = Container::getInstance()->makeWith($abstract, $parameters); $transformer->setKey($this->getKey()); + if (! $transformer instanceof self) { + throw new InvalidTransformerLevelException('Calls to ' . __METHOD__ . ' must return a transformer that is an instance of ' . __CLASS__); + } + return $transformer; } diff --git a/app/Transformers/Api/Application/ServerTransformer.php b/app/Transformers/Api/Application/ServerTransformer.php index 69115d1ed..31eed90c5 100644 --- a/app/Transformers/Api/Application/ServerTransformer.php +++ b/app/Transformers/Api/Application/ServerTransformer.php @@ -97,6 +97,8 @@ class ServerTransformer extends BaseTransformer * * @param \Pterodactyl\Models\Server $server * @return \League\Fractal\Resource\Collection|\League\Fractal\Resource\NullResource + * + * @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException */ public function includeAllocations(Server $server) { diff --git a/app/Transformers/Api/Client/BaseClientTransformer.php b/app/Transformers/Api/Client/BaseClientTransformer.php new file mode 100644 index 000000000..76b618e4d --- /dev/null +++ b/app/Transformers/Api/Client/BaseClientTransformer.php @@ -0,0 +1,44 @@ +getKey(), $resource, AdminAcl::READ); + } + + /** + * Create a new instance of the transformer and pass along the currently + * set API key. + * + * @param string $abstract + * @param array $parameters + * @return self + * + * @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException + */ + protected function makeTransformer(string $abstract, array $parameters = []) + { + $transformer = parent::makeTransformer($abstract, $parameters); + + if (! $transformer instanceof self) { + throw new InvalidTransformerLevelException('Calls to ' . __METHOD__ . ' must return a transformer that is an instance of ' . __CLASS__); + } + + return $transformer; + } +} diff --git a/routes/api-client.php b/routes/api-client.php new file mode 100644 index 000000000..fa4cb6c31 --- /dev/null +++ b/routes/api-client.php @@ -0,0 +1,28 @@ +name('api.client.index'); + +/* +|-------------------------------------------------------------------------- +| Client Control API +|-------------------------------------------------------------------------- +| +| Endpoint: /api/client/servers/{server} +| +*/ +Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateClientAccess::class]], function () { + Route::get('/', 'Server\ServerController@index')->name('api.client.servers.view'); + + Route::post('/command', 'Server\CommandController@index')->name('api.client.servers.command'); + Route::post('/power', 'Server\PowerController@index')->name('api.client.servers.power'); +}); diff --git a/routes/api.php b/routes/api.php deleted file mode 100644 index 96dfe5dde..000000000 --- a/routes/api.php +++ /dev/null @@ -1,27 +0,0 @@ -. - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ -//Route::get('/', 'CoreController@index')->name('api.user'); -// -///* -//|-------------------------------------------------------------------------- -//| Server Controller Routes -//|-------------------------------------------------------------------------- -//| -//| Endpoint: /api/user/server/{server} -//| -//*/ -//Route::group([ -// 'prefix' => '/server/{server}', -// 'middleware' => 'server', -//], function () { -// Route::get('/', 'ServerController@index')->name('api.user.server'); -// -// Route::post('/power', 'ServerController@power')->name('api.user.server.power'); -// Route::post('/command', 'ServerController@command')->name('api.user.server.command'); -//}); diff --git a/tests/Unit/Http/Middleware/Api/Application/AuthenticateUserTest.php b/tests/Unit/Http/Middleware/Api/Application/AuthenticateUserTest.php index 56c7f5ffb..7c0cfc9e7 100644 --- a/tests/Unit/Http/Middleware/Api/Application/AuthenticateUserTest.php +++ b/tests/Unit/Http/Middleware/Api/Application/AuthenticateUserTest.php @@ -1,9 +1,9 @@