Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/app/Http/Controllers/Api/Client/Servers/FileController.php
10284 views
1
<?php
2
3
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
4
5
use Carbon\CarbonImmutable;
6
use Illuminate\Http\Response;
7
use Pterodactyl\Models\Server;
8
use Illuminate\Http\JsonResponse;
9
use Pterodactyl\Facades\Activity;
10
use Pterodactyl\Services\Nodes\NodeJWTService;
11
use Pterodactyl\Repositories\Wings\DaemonFileRepository;
12
use Pterodactyl\Transformers\Api\Client\FileObjectTransformer;
13
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
14
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\CopyFileRequest;
15
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\PullFileRequest;
16
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\ListFilesRequest;
17
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\ChmodFilesRequest;
18
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\DeleteFileRequest;
19
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\RenameFileRequest;
20
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\CreateFolderRequest;
21
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\CompressFilesRequest;
22
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\DecompressFilesRequest;
23
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\GetFileContentsRequest;
24
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\WriteFileContentRequest;
25
26
class FileController extends ClientApiController
27
{
28
/**
29
* FileController constructor.
30
*/
31
public function __construct(
32
private NodeJWTService $jwtService,
33
private DaemonFileRepository $fileRepository,
34
) {
35
parent::__construct();
36
}
37
38
/**
39
* Returns a listing of files in a given directory.
40
*
41
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
42
*/
43
public function directory(ListFilesRequest $request, Server $server): array
44
{
45
$contents = $this->fileRepository
46
->setServer($server)
47
->getDirectory($request->get('directory') ?? '/');
48
49
return $this->fractal->collection($contents)
50
->transformWith($this->getTransformer(FileObjectTransformer::class))
51
->toArray();
52
}
53
54
/**
55
* Return the contents of a specified file for the user.
56
*
57
* @throws \Throwable
58
*/
59
public function contents(GetFileContentsRequest $request, Server $server): Response
60
{
61
$response = $this->fileRepository->setServer($server)->getContent(
62
$request->get('file'),
63
config('pterodactyl.files.max_edit_size')
64
);
65
66
Activity::event('server:file.read')->property('file', $request->get('file'))->log();
67
68
return new Response($response, Response::HTTP_OK, ['Content-Type' => 'text/plain']);
69
}
70
71
/**
72
* Generates a one-time token with a link that the user can use to
73
* download a given file.
74
*
75
* @throws \Throwable
76
*/
77
public function download(GetFileContentsRequest $request, Server $server): array
78
{
79
$token = $this->jwtService
80
->setExpiresAt(CarbonImmutable::now()->addMinutes(15))
81
->setUser($request->user())
82
->setClaims([
83
'file_path' => rawurldecode($request->get('file')),
84
'server_uuid' => $server->uuid,
85
])
86
->handle($server->node, $request->user()->id . $server->uuid);
87
88
Activity::event('server:file.download')->property('file', $request->get('file'))->log();
89
90
return [
91
'object' => 'signed_url',
92
'attributes' => [
93
'url' => sprintf(
94
'%s/download/file?token=%s',
95
$server->node->getConnectionAddress(),
96
$token->toString()
97
),
98
],
99
];
100
}
101
102
/**
103
* Writes the contents of the specified file to the server.
104
*
105
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
106
*/
107
public function write(WriteFileContentRequest $request, Server $server): JsonResponse
108
{
109
$this->fileRepository->setServer($server)->putContent($request->get('file'), $request->getContent());
110
111
Activity::event('server:file.write')->property('file', $request->get('file'))->log();
112
113
return new JsonResponse([], Response::HTTP_NO_CONTENT);
114
}
115
116
/**
117
* Creates a new folder on the server.
118
*
119
* @throws \Throwable
120
*/
121
public function create(CreateFolderRequest $request, Server $server): JsonResponse
122
{
123
$this->fileRepository
124
->setServer($server)
125
->createDirectory($request->input('name'), $request->input('root', '/'));
126
127
Activity::event('server:file.create-directory')
128
->property('name', $request->input('name'))
129
->property('directory', $request->input('root'))
130
->log();
131
132
return new JsonResponse([], Response::HTTP_NO_CONTENT);
133
}
134
135
/**
136
* Renames a file on the remote machine.
137
*
138
* @throws \Throwable
139
*/
140
public function rename(RenameFileRequest $request, Server $server): JsonResponse
141
{
142
$this->fileRepository
143
->setServer($server)
144
->renameFiles($request->input('root'), $request->input('files'));
145
146
Activity::event('server:file.rename')
147
->property('directory', $request->input('root'))
148
->property('files', $request->input('files'))
149
->log();
150
151
return new JsonResponse([], Response::HTTP_NO_CONTENT);
152
}
153
154
/**
155
* Copies a file on the server.
156
*
157
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
158
*/
159
public function copy(CopyFileRequest $request, Server $server): JsonResponse
160
{
161
$this->fileRepository
162
->setServer($server)
163
->copyFile($request->input('location'));
164
165
Activity::event('server:file.copy')->property('file', $request->input('location'))->log();
166
167
return new JsonResponse([], Response::HTTP_NO_CONTENT);
168
}
169
170
/**
171
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
172
*/
173
public function compress(CompressFilesRequest $request, Server $server): array
174
{
175
$file = $this->fileRepository->setServer($server)->compressFiles(
176
$request->input('root'),
177
$request->input('files')
178
);
179
180
Activity::event('server:file.compress')
181
->property('directory', $request->input('root'))
182
->property('files', $request->input('files'))
183
->log();
184
185
return $this->fractal->item($file)
186
->transformWith($this->getTransformer(FileObjectTransformer::class))
187
->toArray();
188
}
189
190
/**
191
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
192
*/
193
public function decompress(DecompressFilesRequest $request, Server $server): JsonResponse
194
{
195
set_time_limit(300);
196
197
$this->fileRepository->setServer($server)->decompressFile(
198
$request->input('root'),
199
$request->input('file')
200
);
201
202
Activity::event('server:file.decompress')
203
->property('directory', $request->input('root'))
204
->property('files', $request->input('file'))
205
->log();
206
207
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
208
}
209
210
/**
211
* Deletes files or folders for the server in the given root directory.
212
*
213
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
214
*/
215
public function delete(DeleteFileRequest $request, Server $server): JsonResponse
216
{
217
$this->fileRepository->setServer($server)->deleteFiles(
218
$request->input('root'),
219
$request->input('files')
220
);
221
222
Activity::event('server:file.delete')
223
->property('directory', $request->input('root'))
224
->property('files', $request->input('files'))
225
->log();
226
227
return new JsonResponse([], Response::HTTP_NO_CONTENT);
228
}
229
230
/**
231
* Updates file permissions for file(s) in the given root directory.
232
*
233
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
234
*/
235
public function chmod(ChmodFilesRequest $request, Server $server): JsonResponse
236
{
237
$this->fileRepository->setServer($server)->chmodFiles(
238
$request->input('root'),
239
$request->input('files')
240
);
241
242
return new JsonResponse([], Response::HTTP_NO_CONTENT);
243
}
244
245
/**
246
* Requests that a file be downloaded from a remote location by Wings.
247
*
248
* @throws \Throwable
249
*/
250
public function pull(PullFileRequest $request, Server $server): JsonResponse
251
{
252
$this->fileRepository->setServer($server)->pull(
253
$request->input('url'),
254
$request->input('directory'),
255
$request->safe(['filename', 'use_header', 'foreground'])
256
);
257
258
Activity::event('server:file.pull')
259
->property('directory', $request->input('directory'))
260
->property('url', $request->input('url'))
261
->log();
262
263
return new JsonResponse([], Response::HTTP_NO_CONTENT);
264
}
265
}
266
267