From ba41fb5095ef13b714dce163911153dbb19ac7bc Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Wed, 13 Jan 2021 09:52:04 -0700 Subject: [PATCH] api(application): add includes for MountTransformer --- .../Api/Application/MountTransformer.php | 80 +++++++++++++++++++ .../scripts/api/admin/mounts/getMounts.ts | 21 ++++- .../scripts/hoc/RequireServerPermission.tsx | 1 + 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/app/Transformers/Api/Application/MountTransformer.php b/app/Transformers/Api/Application/MountTransformer.php index 44a717ba6..be534af56 100644 --- a/app/Transformers/Api/Application/MountTransformer.php +++ b/app/Transformers/Api/Application/MountTransformer.php @@ -3,9 +3,17 @@ namespace Pterodactyl\Transformers\Api\Application; use Pterodactyl\Models\Mount; +use Pterodactyl\Services\Acl\Api\AdminAcl; class MountTransformer extends BaseTransformer { + /** + * List of resources that can be included. + * + * @var array + */ + protected $availableIncludes = ['eggs', 'nodes', 'servers']; + /** * Return the resource name for the JSONAPI output. * @@ -35,4 +43,76 @@ class MountTransformer extends BaseTransformer 'user_mountable' => $model->user_mountable, ]; } + + /** + * Return the eggs associated with this mount. + * + * @param \Pterodactyl\Models\Mount $mount + * + * @return \League\Fractal\Resource\Collection|\League\Fractal\Resource\NullResource + * @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + public function includeEggs(Mount $mount) + { + if (! $this->authorize(AdminAcl::RESOURCE_EGGS)) { + return $this->null(); + } + + $mount->loadMissing('eggs'); + + return $this->collection( + $mount->getRelation('eggs'), + $this->makeTransformer(EggTransformer::class), + 'egg', + ); + } + + /** + * Return the nodes associated with this mount. + * + * @param \Pterodactyl\Models\Mount $mount + * + * @return \League\Fractal\Resource\Collection|\League\Fractal\Resource\NullResource + * @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + public function includeNodes(Mount $mount) + { + if (! $this->authorize(AdminAcl::RESOURCE_NODES)) { + return $this->null(); + } + + $mount->loadMissing('nodes'); + + return $this->collection( + $mount->getRelation('nodes'), + $this->makeTransformer(NodeTransformer::class), + 'node', + ); + } + + /** + * Return the servers associated with this mount. + * + * @param \Pterodactyl\Models\Mount $mount + * + * @return \League\Fractal\Resource\Collection|\League\Fractal\Resource\NullResource + * @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + public function includeServers(Mount $mount) + { + if (! $this->authorize(AdminAcl::RESOURCE_SERVERS)) { + return $this->null(); + } + + $mount->loadMissing('servers'); + + return $this->collection( + $mount->getRelation('servers'), + $this->makeTransformer(ServerTransformer::class), + 'server', + ); + } } diff --git a/resources/scripts/api/admin/mounts/getMounts.ts b/resources/scripts/api/admin/mounts/getMounts.ts index a8c1b2917..b05981df9 100644 --- a/resources/scripts/api/admin/mounts/getMounts.ts +++ b/resources/scripts/api/admin/mounts/getMounts.ts @@ -1,6 +1,9 @@ -import http, { FractalResponseData, getPaginationSet, PaginatedResult } from '@/api/http'; +import http, { FractalResponseData, FractalResponseList, getPaginationSet, PaginatedResult } from '@/api/http'; import { createContext, useContext } from 'react'; import useSWR from 'swr'; +import { Egg, rawDataToEgg } from '@/api/admin/eggs/getEgg'; +import { Node, rawDataToNode } from '@/api/admin/nodes/getNodes'; +import { Server, rawDataToServer } from '@/api/admin/servers/getServers'; export interface Mount { id: number; @@ -13,6 +16,12 @@ export interface Mount { userMountable: boolean; createdAt: Date; updatedAt: Date; + + relations: { + eggs: Egg[] | undefined; + nodes: Node[] | undefined; + servers: Server[] | undefined; + }; } export const rawDataToMount = ({ attributes }: FractalResponseData): Mount => ({ @@ -26,6 +35,12 @@ export const rawDataToMount = ({ attributes }: FractalResponseData): Mount => ({ userMountable: attributes.user_mountable, createdAt: new Date(attributes.created_at), updatedAt: new Date(attributes.updated_at), + + relations: { + eggs: ((attributes.relationships?.eggs as FractalResponseList | undefined)?.data || []).map(rawDataToEgg), + nodes: ((attributes.relationships?.nodes as FractalResponseList | undefined)?.data || []).map(rawDataToNode), + servers: ((attributes.relationships?.servers as FractalResponseList | undefined)?.data || []).map(rawDataToServer), + }, }); interface ctx { @@ -35,11 +50,11 @@ interface ctx { export const Context = createContext({ page: 1, setPage: () => 1 }); -export default () => { +export default (include: string[] = []) => { const { page } = useContext(Context); return useSWR>([ 'mounts', page ], async () => { - const { data } = await http.get('/api/application/mounts', { params: { page } }); + const { data } = await http.get('/api/application/mounts', { params: { include: include.join(','), page } }); return ({ items: (data.data || []).map(rawDataToMount), diff --git a/resources/scripts/hoc/RequireServerPermission.tsx b/resources/scripts/hoc/RequireServerPermission.tsx index ba825a59e..d45e98e07 100644 --- a/resources/scripts/hoc/RequireServerPermission.tsx +++ b/resources/scripts/hoc/RequireServerPermission.tsx @@ -1,6 +1,7 @@ import React from 'react'; import Can from '@/components/elements/Can'; import ScreenBlock from '@/components/screens/ScreenBlock'; + export interface RequireServerPermissionProps { permissions: string | string[] }