Skip to content

Commit b00def2

Browse files
committed
Switch to JSON from TEXT when storing denylist items for an egg; closes pterodactyl#3034
1 parent b7d1c45 commit b00def2

File tree

7 files changed

+89
-30
lines changed

7 files changed

+89
-30
lines changed

app/Http/Requests/Admin/Egg/EggFormRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function rules()
2222
'name' => 'required|string|max:191',
2323
'description' => 'nullable|string',
2424
'docker_images' => 'required|string',
25-
'file_denylist' => 'string',
25+
'file_denylist' => 'array',
2626
'startup' => 'required|string',
2727
'config_from' => 'sometimes|bail|nullable|numeric',
2828
'config_stop' => 'required_without:config_from|nullable|string|max:191',

app/Models/Egg.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* @property string $docker_image -- deprecated, use $docker_images
1414
* @property string $update_url
1515
* @property array $docker_images
16-
* @property string $file_denylist
16+
* @property array|null $file_denylist
1717
* @property string|null $config_files
1818
* @property string|null $config_startup
1919
* @property string|null $config_logs
@@ -105,6 +105,7 @@ class Egg extends Model
105105
'copy_script_from' => 'integer',
106106
'features' => 'array',
107107
'docker_images' => 'array',
108+
'file_denylist' => 'array',
108109
];
109110

110111
/**
@@ -117,6 +118,8 @@ class Egg extends Model
117118
'description' => 'string|nullable',
118119
'features' => 'array|nullable',
119120
'author' => 'required|string|email',
121+
'file_denylist' => 'array|nullable',
122+
'file_denylist.*' => 'string',
120123
'docker_images' => 'required|array|min:1',
121124
'docker_images.*' => 'required|string',
122125
'startup' => 'required|nullable|string',
@@ -133,6 +136,7 @@ class Egg extends Model
133136
*/
134137
protected $attributes = [
135138
'features' => null,
139+
'file_denylist' => null,
136140
'config_stop' => null,
137141
'config_startup' => null,
138142
'config_logs' => null,
@@ -260,7 +264,7 @@ public function getInheritFeaturesAttribute()
260264
* Returns the features available to this egg from the parent configuration if there are
261265
* no features defined for this egg specifically and there is a parent egg configured.
262266
*
263-
* @return string
267+
* @return string[]|null
264268
*/
265269
public function getInheritFileDenylistAttribute()
266270
{

app/Services/Eggs/Sharing/EggExporterService.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Pterodactyl\Services\Eggs\Sharing;
44

55
use Carbon\Carbon;
6+
use Illuminate\Support\Collection;
7+
use Pterodactyl\Models\EggVariable;
68
use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
79

810
class EggExporterService
@@ -41,7 +43,9 @@ public function handle(int $egg): string
4143
'description' => $egg->description,
4244
'features' => $egg->features,
4345
'images' => $egg->docker_images,
44-
'file_denylist' => $egg->inherit_file_denylist,
46+
'file_denylist' => Collection::make($egg->inherit_file_denylist)->filter(function ($value) {
47+
return !empty($value);
48+
}),
4549
'startup' => $egg->startup,
4650
'config' => [
4751
'files' => $egg->inherit_config_files,
@@ -56,10 +60,10 @@ public function handle(int $egg): string
5660
'entrypoint' => $egg->copy_script_entry,
5761
],
5862
],
59-
'variables' => $egg->variables->transform(function ($item) {
60-
return collect($item->toArray())->except([
61-
'id', 'egg_id', 'created_at', 'updated_at',
62-
])->toArray();
63+
'variables' => $egg->variables->transform(function (EggVariable $item) {
64+
return Collection::make($item->toArray())
65+
->except(['id', 'egg_id', 'created_at', 'updated_at'])
66+
->toArray();
6367
}),
6468
];
6569

app/Services/Eggs/Sharing/EggImporterService.php

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
use Ramsey\Uuid\Uuid;
66
use Pterodactyl\Models\Egg;
7+
use Illuminate\Support\Arr;
78
use Illuminate\Http\UploadedFile;
9+
use Illuminate\Support\Collection;
810
use Illuminate\Database\ConnectionInterface;
911
use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
1012
use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
@@ -63,43 +65,47 @@ public function handle(UploadedFile $file, int $nest): Egg
6365
throw new InvalidFileUploadException(sprintf('The selected file ["%s"] was not in a valid format to import. (is_file: %s is_valid: %s err_code: %s err: %s)', $file->getFilename(), $file->isFile() ? 'true' : 'false', $file->isValid() ? 'true' : 'false', $file->getError(), $file->getErrorMessage()));
6466
}
6567

66-
$parsed = json_decode($file->openFile()->fread($file->getSize()));
68+
/** @var array $parsed */
69+
$parsed = json_decode($file->openFile()->fread($file->getSize()), true);
6770
if (json_last_error() !== 0) {
6871
throw new BadJsonFormatException(trans('exceptions.nest.importer.json_error', ['error' => json_last_error_msg()]));
6972
}
7073

71-
if (object_get($parsed, 'meta.version') !== 'PTDL_v1') {
74+
if (Arr::get($parsed, 'meta.version') !== 'PTDL_v1') {
7275
throw new InvalidFileUploadException(trans('exceptions.nest.importer.invalid_json_provided'));
7376
}
7477

7578
$nest = $this->nestRepository->getWithEggs($nest);
7679
$this->connection->beginTransaction();
7780

81+
/** @var \Pterodactyl\Models\Egg $egg */
7882
$egg = $this->repository->create([
7983
'uuid' => Uuid::uuid4()->toString(),
8084
'nest_id' => $nest->id,
81-
'author' => object_get($parsed, 'author'),
82-
'name' => object_get($parsed, 'name'),
83-
'description' => object_get($parsed, 'description'),
84-
'features' => object_get($parsed, 'features'),
85+
'author' => Arr::get($parsed, 'author'),
86+
'name' => Arr::get($parsed, 'name'),
87+
'description' => Arr::get($parsed, 'description'),
88+
'features' => Arr::get($parsed, 'features'),
8589
// Maintain backwards compatability for eggs that are still using the old single image
8690
// string format. New eggs can provide an array of Docker images that can be used.
87-
'docker_images' => object_get($parsed, 'images') ?? [object_get($parsed, 'image')],
88-
'file_denylist' => implode(PHP_EOL, object_get($parsed, 'file_denylist') ?? []),
89-
'update_url' => object_get($parsed, 'meta.update_url'),
90-
'config_files' => object_get($parsed, 'config.files'),
91-
'config_startup' => object_get($parsed, 'config.startup'),
92-
'config_logs' => object_get($parsed, 'config.logs'),
93-
'config_stop' => object_get($parsed, 'config.stop'),
94-
'startup' => object_get($parsed, 'startup'),
95-
'script_install' => object_get($parsed, 'scripts.installation.script'),
96-
'script_entry' => object_get($parsed, 'scripts.installation.entrypoint'),
97-
'script_container' => object_get($parsed, 'scripts.installation.container'),
91+
'docker_images' => Arr::get($parsed, 'images') ?? [Arr::get($parsed, 'image')],
92+
'file_denylist' => Collection::make(Arr::get($parsed, 'file_denylist'))->filter(function ($value) {
93+
return !empty($value);
94+
}),
95+
'update_url' => Arr::get($parsed, 'meta.update_url'),
96+
'config_files' => Arr::get($parsed, 'config.files'),
97+
'config_startup' => Arr::get($parsed, 'config.startup'),
98+
'config_logs' => Arr::get($parsed, 'config.logs'),
99+
'config_stop' => Arr::get($parsed, 'config.stop'),
100+
'startup' => Arr::get($parsed, 'startup'),
101+
'script_install' => Arr::get($parsed, 'scripts.installation.script'),
102+
'script_entry' => Arr::get($parsed, 'scripts.installation.entrypoint'),
103+
'script_container' => Arr::get($parsed, 'scripts.installation.container'),
98104
'copy_script_from' => null,
99105
], true, true);
100106

101-
collect($parsed->variables)->each(function ($variable) use ($egg) {
102-
$this->eggVariableRepository->create(array_merge((array) $variable, [
107+
Collection::make($parsed['variables'] ?? [])->each(function (array $variable) use ($egg) {
108+
$this->eggVariableRepository->create(array_merge($variable, [
103109
'egg_id' => $egg->id,
104110
]));
105111
});

app/Services/Servers/ServerConfigurationStructureService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ protected function returnCurrentFormat(Server $server): array
8080
}),
8181
'egg' => [
8282
'id' => $server->egg->uuid,
83-
'file_denylist' => explode(PHP_EOL, $server->egg->inherit_file_denylist),
83+
'file_denylist' => $server->egg->inherit_file_denylist,
8484
],
8585
];
8686
}

app/Transformers/Api/Application/EggTransformer.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Pterodactyl\Models\Egg;
66
use Pterodactyl\Models\Nest;
77
use Pterodactyl\Models\Server;
8+
use Illuminate\Support\Collection;
89
use Pterodactyl\Models\EggVariable;
910
use Pterodactyl\Services\Acl\Api\AdminAcl;
1011

@@ -16,7 +17,11 @@ class EggTransformer extends BaseTransformer
1617
* @var array
1718
*/
1819
protected $availableIncludes = [
19-
'nest', 'servers', 'config', 'script', 'variables',
20+
'nest',
21+
'servers',
22+
'config',
23+
'script',
24+
'variables',
2025
];
2126

2227
/**
@@ -52,7 +57,7 @@ public function transform(Egg $model)
5257
'startup' => json_decode($model->config_startup, true),
5358
'stop' => $model->config_stop,
5459
'logs' => json_decode($model->config_logs, true),
55-
'file_denylist' => explode(PHP_EOL, $model->file_denylist),
60+
'file_denylist' => $model->file_denylist,
5661
'extends' => $model->config_from,
5762
],
5863
'startup' => $model->startup,
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class UpdateFileDenylistToJson extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('eggs', function (Blueprint $table) {
17+
$table->dropColumn('file_denylist');
18+
});
19+
20+
Schema::table('eggs', function (Blueprint $table) {
21+
$table->json('file_denylist')->nullable()->after('docker_images');
22+
});
23+
}
24+
25+
/**
26+
* Reverse the migrations.
27+
*
28+
* @return void
29+
*/
30+
public function down()
31+
{
32+
Schema::table('eggs', function (Blueprint $table) {
33+
$table->dropColumn('file_denylist');
34+
});
35+
36+
Schema::table('eggs', function (Blueprint $table) {
37+
$table->text('file_denylist')->after('docker_images');
38+
});
39+
}
40+
}

0 commit comments

Comments
 (0)