Path: blob/1.0-develop/app/Http/Controllers/Api/Client/Servers/FileController.php
10284 views
<?php12namespace Pterodactyl\Http\Controllers\Api\Client\Servers;34use Carbon\CarbonImmutable;5use Illuminate\Http\Response;6use Pterodactyl\Models\Server;7use Illuminate\Http\JsonResponse;8use Pterodactyl\Facades\Activity;9use Pterodactyl\Services\Nodes\NodeJWTService;10use Pterodactyl\Repositories\Wings\DaemonFileRepository;11use Pterodactyl\Transformers\Api\Client\FileObjectTransformer;12use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;13use Pterodactyl\Http\Requests\Api\Client\Servers\Files\CopyFileRequest;14use Pterodactyl\Http\Requests\Api\Client\Servers\Files\PullFileRequest;15use Pterodactyl\Http\Requests\Api\Client\Servers\Files\ListFilesRequest;16use Pterodactyl\Http\Requests\Api\Client\Servers\Files\ChmodFilesRequest;17use Pterodactyl\Http\Requests\Api\Client\Servers\Files\DeleteFileRequest;18use Pterodactyl\Http\Requests\Api\Client\Servers\Files\RenameFileRequest;19use Pterodactyl\Http\Requests\Api\Client\Servers\Files\CreateFolderRequest;20use Pterodactyl\Http\Requests\Api\Client\Servers\Files\CompressFilesRequest;21use Pterodactyl\Http\Requests\Api\Client\Servers\Files\DecompressFilesRequest;22use Pterodactyl\Http\Requests\Api\Client\Servers\Files\GetFileContentsRequest;23use Pterodactyl\Http\Requests\Api\Client\Servers\Files\WriteFileContentRequest;2425class FileController extends ClientApiController26{27/**28* FileController constructor.29*/30public function __construct(31private NodeJWTService $jwtService,32private DaemonFileRepository $fileRepository,33) {34parent::__construct();35}3637/**38* Returns a listing of files in a given directory.39*40* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException41*/42public function directory(ListFilesRequest $request, Server $server): array43{44$contents = $this->fileRepository45->setServer($server)46->getDirectory($request->get('directory') ?? '/');4748return $this->fractal->collection($contents)49->transformWith($this->getTransformer(FileObjectTransformer::class))50->toArray();51}5253/**54* Return the contents of a specified file for the user.55*56* @throws \Throwable57*/58public function contents(GetFileContentsRequest $request, Server $server): Response59{60$response = $this->fileRepository->setServer($server)->getContent(61$request->get('file'),62config('pterodactyl.files.max_edit_size')63);6465Activity::event('server:file.read')->property('file', $request->get('file'))->log();6667return new Response($response, Response::HTTP_OK, ['Content-Type' => 'text/plain']);68}6970/**71* Generates a one-time token with a link that the user can use to72* download a given file.73*74* @throws \Throwable75*/76public function download(GetFileContentsRequest $request, Server $server): array77{78$token = $this->jwtService79->setExpiresAt(CarbonImmutable::now()->addMinutes(15))80->setUser($request->user())81->setClaims([82'file_path' => rawurldecode($request->get('file')),83'server_uuid' => $server->uuid,84])85->handle($server->node, $request->user()->id . $server->uuid);8687Activity::event('server:file.download')->property('file', $request->get('file'))->log();8889return [90'object' => 'signed_url',91'attributes' => [92'url' => sprintf(93'%s/download/file?token=%s',94$server->node->getConnectionAddress(),95$token->toString()96),97],98];99}100101/**102* Writes the contents of the specified file to the server.103*104* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException105*/106public function write(WriteFileContentRequest $request, Server $server): JsonResponse107{108$this->fileRepository->setServer($server)->putContent($request->get('file'), $request->getContent());109110Activity::event('server:file.write')->property('file', $request->get('file'))->log();111112return new JsonResponse([], Response::HTTP_NO_CONTENT);113}114115/**116* Creates a new folder on the server.117*118* @throws \Throwable119*/120public function create(CreateFolderRequest $request, Server $server): JsonResponse121{122$this->fileRepository123->setServer($server)124->createDirectory($request->input('name'), $request->input('root', '/'));125126Activity::event('server:file.create-directory')127->property('name', $request->input('name'))128->property('directory', $request->input('root'))129->log();130131return new JsonResponse([], Response::HTTP_NO_CONTENT);132}133134/**135* Renames a file on the remote machine.136*137* @throws \Throwable138*/139public function rename(RenameFileRequest $request, Server $server): JsonResponse140{141$this->fileRepository142->setServer($server)143->renameFiles($request->input('root'), $request->input('files'));144145Activity::event('server:file.rename')146->property('directory', $request->input('root'))147->property('files', $request->input('files'))148->log();149150return new JsonResponse([], Response::HTTP_NO_CONTENT);151}152153/**154* Copies a file on the server.155*156* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException157*/158public function copy(CopyFileRequest $request, Server $server): JsonResponse159{160$this->fileRepository161->setServer($server)162->copyFile($request->input('location'));163164Activity::event('server:file.copy')->property('file', $request->input('location'))->log();165166return new JsonResponse([], Response::HTTP_NO_CONTENT);167}168169/**170* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException171*/172public function compress(CompressFilesRequest $request, Server $server): array173{174$file = $this->fileRepository->setServer($server)->compressFiles(175$request->input('root'),176$request->input('files')177);178179Activity::event('server:file.compress')180->property('directory', $request->input('root'))181->property('files', $request->input('files'))182->log();183184return $this->fractal->item($file)185->transformWith($this->getTransformer(FileObjectTransformer::class))186->toArray();187}188189/**190* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException191*/192public function decompress(DecompressFilesRequest $request, Server $server): JsonResponse193{194set_time_limit(300);195196$this->fileRepository->setServer($server)->decompressFile(197$request->input('root'),198$request->input('file')199);200201Activity::event('server:file.decompress')202->property('directory', $request->input('root'))203->property('files', $request->input('file'))204->log();205206return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);207}208209/**210* Deletes files or folders for the server in the given root directory.211*212* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException213*/214public function delete(DeleteFileRequest $request, Server $server): JsonResponse215{216$this->fileRepository->setServer($server)->deleteFiles(217$request->input('root'),218$request->input('files')219);220221Activity::event('server:file.delete')222->property('directory', $request->input('root'))223->property('files', $request->input('files'))224->log();225226return new JsonResponse([], Response::HTTP_NO_CONTENT);227}228229/**230* Updates file permissions for file(s) in the given root directory.231*232* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException233*/234public function chmod(ChmodFilesRequest $request, Server $server): JsonResponse235{236$this->fileRepository->setServer($server)->chmodFiles(237$request->input('root'),238$request->input('files')239);240241return new JsonResponse([], Response::HTTP_NO_CONTENT);242}243244/**245* Requests that a file be downloaded from a remote location by Wings.246*247* @throws \Throwable248*/249public function pull(PullFileRequest $request, Server $server): JsonResponse250{251$this->fileRepository->setServer($server)->pull(252$request->input('url'),253$request->input('directory'),254$request->safe(['filename', 'use_header', 'foreground'])255);256257Activity::event('server:file.pull')258->property('directory', $request->input('directory'))259->property('url', $request->input('url'))260->log();261262return new JsonResponse([], Response::HTTP_NO_CONTENT);263}264}265266267