Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/tests/Integration/Services/Servers/StartupModificationServiceTest.php
7460 views
1
<?php
2
3
namespace Pterodactyl\Tests\Integration\Services\Servers;
4
5
use Exception;
6
use Pterodactyl\Models\Nest;
7
use Pterodactyl\Models\User;
8
use Pterodactyl\Models\Server;
9
use Pterodactyl\Models\ServerVariable;
10
use Illuminate\Validation\ValidationException;
11
use Pterodactyl\Tests\Integration\IntegrationTestCase;
12
use Illuminate\Database\Eloquent\ModelNotFoundException;
13
use Pterodactyl\Services\Servers\StartupModificationService;
14
15
class StartupModificationServiceTest extends IntegrationTestCase
16
{
17
/**
18
* Test that a non-admin request to modify the server startup parameters does
19
* not perform any egg or nest updates. This also attempts to pass through an
20
* egg_id variable which should have no impact if the request is coming from
21
* a non-admin entity.
22
*/
23
public function testNonAdminCanModifyServerVariables()
24
{
25
$server = $this->createServerModel();
26
27
try {
28
$this->app->make(StartupModificationService::class)->handle($server, [
29
'egg_id' => $server->egg_id + 1,
30
'environment' => [
31
'BUNGEE_VERSION' => '$$',
32
'SERVER_JARFILE' => 'server.jar',
33
],
34
]);
35
36
$this->fail('This assertion should not be called.');
37
} catch (\Exception $exception) {
38
$this->assertInstanceOf(ValidationException::class, $exception);
39
40
/** @var ValidationException $exception */
41
$errors = $exception->validator->errors()->toArray();
42
43
$this->assertCount(1, $errors);
44
$this->assertArrayHasKey('environment.BUNGEE_VERSION', $errors);
45
$this->assertCount(1, $errors['environment.BUNGEE_VERSION']);
46
$this->assertSame('The Bungeecord Version variable may only contain letters and numbers.', $errors['environment.BUNGEE_VERSION'][0]);
47
}
48
49
ServerVariable::query()->where('variable_id', $server->variables[1]->id)->delete();
50
51
$result = $this->getService()
52
->handle($server, [
53
'egg_id' => $server->egg_id + 1,
54
'startup' => 'random gibberish',
55
'environment' => [
56
'BUNGEE_VERSION' => '1234',
57
'SERVER_JARFILE' => 'test.jar',
58
],
59
]);
60
61
$this->assertInstanceOf(Server::class, $result);
62
$this->assertCount(2, $result->variables);
63
$this->assertSame($server->startup, $result->startup);
64
$this->assertSame('1234', $result->variables[0]->server_value);
65
$this->assertSame('test.jar', $result->variables[1]->server_value);
66
}
67
68
/**
69
* Test that modifying an egg as an admin properly updates the data for the server.
70
*/
71
public function testServerIsProperlyModifiedAsAdminUser()
72
{
73
/** @var \Pterodactyl\Models\Egg $nextEgg */
74
$nextEgg = Nest::query()->findOrFail(2)->eggs()->firstOrFail();
75
76
$server = $this->createServerModel(['egg_id' => 1]);
77
78
$this->assertNotSame($nextEgg->id, $server->egg_id);
79
$this->assertNotSame($nextEgg->nest_id, $server->nest_id);
80
81
$response = $this->getService()
82
->setUserLevel(User::USER_LEVEL_ADMIN)
83
->handle($server, [
84
'egg_id' => $nextEgg->id,
85
'startup' => 'sample startup',
86
'skip_scripts' => true,
87
'docker_image' => 'docker/hodor',
88
]);
89
90
$this->assertInstanceOf(Server::class, $response);
91
$this->assertSame($nextEgg->id, $response->egg_id);
92
$this->assertSame($nextEgg->nest_id, $response->nest_id);
93
$this->assertSame('sample startup', $response->startup);
94
$this->assertSame('docker/hodor', $response->image);
95
$this->assertTrue($response->skip_scripts);
96
// Make sure we don't revert back to a lurking bug that causes servers to get marked
97
// as not installed when you modify the startup...
98
$this->assertTrue($response->isInstalled());
99
}
100
101
/**
102
* Test that hidden variables can be updated by an admin but are not affected by a
103
* regular user who attempts to pass them through.
104
*/
105
public function testEnvironmentVariablesCanBeUpdatedByAdmin()
106
{
107
$server = $this->createServerModel();
108
$server->loadMissing(['egg', 'variables']);
109
110
$clone = $this->cloneEggAndVariables($server->egg);
111
// This makes the BUNGEE_VERSION variable not user editable.
112
$clone->variables()->first()->update([
113
'user_editable' => false,
114
]);
115
116
$server->fill(['egg_id' => $clone->id])->saveOrFail();
117
$server->refresh();
118
119
ServerVariable::query()->updateOrCreate([
120
'server_id' => $server->id,
121
'variable_id' => $server->variables[0]->id,
122
], ['variable_value' => 'EXIST']);
123
124
$response = $this->getService()->handle($server, [
125
'environment' => [
126
'BUNGEE_VERSION' => '1234',
127
'SERVER_JARFILE' => 'test.jar',
128
],
129
]);
130
131
$this->assertCount(2, $response->variables);
132
$this->assertSame('EXIST', $response->variables[0]->server_value);
133
$this->assertSame('test.jar', $response->variables[1]->server_value);
134
135
$response = $this->getService()
136
->setUserLevel(User::USER_LEVEL_ADMIN)
137
->handle($server, [
138
'environment' => [
139
'BUNGEE_VERSION' => '1234',
140
'SERVER_JARFILE' => 'test.jar',
141
],
142
]);
143
144
$this->assertCount(2, $response->variables);
145
$this->assertSame('1234', $response->variables[0]->server_value);
146
$this->assertSame('test.jar', $response->variables[1]->server_value);
147
}
148
149
/**
150
* Test that passing an invalid egg ID into the function throws an exception
151
* rather than silently failing or skipping.
152
*/
153
public function testInvalidEggIdTriggersException()
154
{
155
$server = $this->createServerModel();
156
157
$this->expectException(ModelNotFoundException::class);
158
159
$this->getService()
160
->setUserLevel(User::USER_LEVEL_ADMIN)
161
->handle($server, ['egg_id' => 123456789]);
162
}
163
164
private function getService(): StartupModificationService
165
{
166
return $this->app->make(StartupModificationService::class);
167
}
168
}
169
170