From 42fb9fdbd944503e39c531c2c13a378d482747ad Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Fri, 10 Apr 2020 13:04:11 -0600 Subject: [PATCH 1/4] Add the ability for a node to fetch a list of all servers it has been assigned --- .../Repository/ServerRepositoryInterface.php | 12 ++++++ .../Servers/ServerDetailsController.php | 39 ++++++++++++++++++- .../Eloquent/ServerRepository.php | 17 ++++++++ routes/api-remote.php | 3 ++ 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/app/Contracts/Repository/ServerRepositoryInterface.php b/app/Contracts/Repository/ServerRepositoryInterface.php index 71169088c..8851c5798 100644 --- a/app/Contracts/Repository/ServerRepositoryInterface.php +++ b/app/Contracts/Repository/ServerRepositoryInterface.php @@ -171,4 +171,16 @@ interface ServerRepositoryInterface extends RepositoryInterface, SearchableInter * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ public function loadAllServersForNode(int $node, int $limit): LengthAwarePaginator; + + /** + * Returns every server that exists for a given node. + * + * This is different from {@see loadAllServersForNode} because + * it does not paginate the response. + * + * @param int $node + * + * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection + */ + public function loadEveryServerForNode(int $node); } diff --git a/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php b/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php index c9d9f4bc6..256566a31 100644 --- a/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php +++ b/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php @@ -5,6 +5,7 @@ namespace Pterodactyl\Http\Controllers\Api\Remote\Servers; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; use Pterodactyl\Http\Controllers\Controller; +use Pterodactyl\Repositories\Eloquent\NodeRepository; use Pterodactyl\Services\Eggs\EggConfigurationService; use Pterodactyl\Repositories\Eloquent\ServerRepository; use Pterodactyl\Services\Servers\ServerConfigurationStructureService; @@ -26,21 +27,29 @@ class ServerDetailsController extends Controller */ private $configurationStructureService; + /** + * @var \Pterodactyl\Repositories\Eloquent\NodeRepository + */ + private $nodeRepository; + /** * ServerConfigurationController constructor. * * @param \Pterodactyl\Repositories\Eloquent\ServerRepository $repository * @param \Pterodactyl\Services\Servers\ServerConfigurationStructureService $configurationStructureService * @param \Pterodactyl\Services\Eggs\EggConfigurationService $eggConfigurationService + * @param \Pterodactyl\Repositories\Eloquent\NodeRepository $nodeRepository */ public function __construct( ServerRepository $repository, ServerConfigurationStructureService $configurationStructureService, - EggConfigurationService $eggConfigurationService + EggConfigurationService $eggConfigurationService, + NodeRepository $nodeRepository ) { $this->eggConfigurationService = $eggConfigurationService; $this->repository = $repository; $this->configurationStructureService = $configurationStructureService; + $this->nodeRepository = $nodeRepository; } /** @@ -62,4 +71,32 @@ class ServerDetailsController extends Controller 'process_configuration' => $this->eggConfigurationService->handle($server), ]); } + + /** + * Lists all servers with their configurations that are assigned to the requesting node. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\JsonResponse + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException + */ + public function list(Request $request) + { + $authorization = substr($request->header('Authorization'), 7); + + $node = $this->nodeRepository->findFirstWhere([ 'daemonSecret' => $authorization ]); + $servers = $this->repository->loadEveryServerForNode($node->id); + + $configurations = []; + + foreach ($servers as $server) { + $configurations[$server->uuid] = [ + 'settings' => $this->configurationStructureService->handle($server), + 'process_configuration' => $this->eggConfigurationService->handle($server), + ]; + } + + return JsonResponse::create($configurations); + } } diff --git a/app/Repositories/Eloquent/ServerRepository.php b/app/Repositories/Eloquent/ServerRepository.php index 874b1cc95..820423487 100644 --- a/app/Repositories/Eloquent/ServerRepository.php +++ b/app/Repositories/Eloquent/ServerRepository.php @@ -378,4 +378,21 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt ->where('node_id', '=', $node) ->paginate($limit); } + + /** + * Returns every server that exists for a given node. + * + * This is different from {@see loadAllServersForNode} because + * it does not paginate the response. + * + * @param int $node + * + * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection + */ + public function loadEveryServerForNode(int $node) + { + return $this->getBuilder() + ->with('nest') + ->where('node_id', '=', $node)->get(); + } } diff --git a/routes/api-remote.php b/routes/api-remote.php index 1d09562e8..3cf564e83 100644 --- a/routes/api-remote.php +++ b/routes/api-remote.php @@ -7,6 +7,9 @@ Route::post('/download-file', 'FileDownloadController@index'); // Routes for the Wings daemon. Route::post('/sftp/auth', 'SftpAuthenticationController'); + +Route::get('/servers', 'Servers\ServerDetailsController@list'); + Route::group(['prefix' => '/servers/{uuid}'], function () { Route::get('/', 'Servers\ServerDetailsController'); Route::get('/install', 'Servers\ServerInstallController@index'); From 3163517f8d8ca8995de99b9e98a0db3b0369aa6b Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Fri, 10 Apr 2020 13:06:10 -0600 Subject: [PATCH 2/4] Add linebreak because code style is important --- app/Repositories/Eloquent/ServerRepository.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Repositories/Eloquent/ServerRepository.php b/app/Repositories/Eloquent/ServerRepository.php index 820423487..e3e398d5e 100644 --- a/app/Repositories/Eloquent/ServerRepository.php +++ b/app/Repositories/Eloquent/ServerRepository.php @@ -393,6 +393,7 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt { return $this->getBuilder() ->with('nest') - ->where('node_id', '=', $node)->get(); + ->where('node_id', '=', $node) + ->get(); } } From 87e95f4195d15419ccd7d5a70d6527025b941e73 Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Fri, 10 Apr 2020 13:08:43 -0600 Subject: [PATCH 3/4] Fix StyleCI --- .../Controllers/Api/Remote/Servers/ServerDetailsController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php b/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php index 256566a31..c60b9e1a0 100644 --- a/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php +++ b/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php @@ -85,7 +85,7 @@ class ServerDetailsController extends Controller { $authorization = substr($request->header('Authorization'), 7); - $node = $this->nodeRepository->findFirstWhere([ 'daemonSecret' => $authorization ]); + $node = $this->nodeRepository->findFirstWhere(['daemonSecret' => $authorization]); $servers = $this->repository->loadEveryServerForNode($node->id); $configurations = []; From 658a959e5da48610a04f083481e41c2646db8d1f Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Fri, 10 Apr 2020 17:54:50 -0600 Subject: [PATCH 4/4] Fix trailing comma in DaemonAuthenticate.php, change ServerDetailsController.php to use node authentication --- .../Api/Remote/Servers/ServerDetailsController.php | 4 +--- app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php b/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php index c60b9e1a0..2e4aa8ab1 100644 --- a/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php +++ b/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php @@ -83,9 +83,7 @@ class ServerDetailsController extends Controller */ public function list(Request $request) { - $authorization = substr($request->header('Authorization'), 7); - - $node = $this->nodeRepository->findFirstWhere(['daemonSecret' => $authorization]); + $node = $request->attributes->get('node'); $servers = $this->repository->loadEveryServerForNode($node->id); $configurations = []; diff --git a/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php b/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php index 8735c8d26..a2b1e716e 100644 --- a/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php +++ b/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php @@ -69,7 +69,7 @@ class DaemonAuthenticate // Ensure that all of the correct parts are provided in the header. if (count($parts) !== 2 || empty($parts[0]) || empty($parts[1])) { throw new BadRequestHttpException( - 'The Authorization headed provided was not in a valid format.', + 'The Authorization headed provided was not in a valid format.' ); }