Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/tests/Integration/Api/Client/Server/Subuser/DeleteSubuserTest.php
10259 views
1
<?php
2
3
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Subuser;
4
5
use Ramsey\Uuid\Uuid;
6
use Mockery\MockInterface;
7
use Pterodactyl\Models\User;
8
use Pterodactyl\Models\Subuser;
9
use Pterodactyl\Models\Permission;
10
use PHPUnit\Framework\Attributes\TestWith;
11
use Pterodactyl\Repositories\Wings\DaemonRevocationRepository;
12
use Pterodactyl\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
13
14
class DeleteSubuserTest extends ClientApiIntegrationTestCase
15
{
16
/**
17
* Guards against PHP's exciting behavior where a string can be cast to an int and only
18
* the first numeric digits are returned. This causes UUIDs to be returned as an int when
19
* looking up users, thus returning the wrong subusers (or no subuser at all).
20
*
21
* For example, 12aaaaaa-bbbb-cccc-ddddeeeeffff would be cast to "12" if you tried to cast
22
* it to an integer. Then, in the deep API middlewares you would end up trying to load a user
23
* with an ID of 12, which may or may not exist and be wrongly assigned to the model object.
24
*
25
* @see https://github.com/pterodactyl/panel/issues/2359
26
*/
27
#[TestWith([null])]
28
#[TestWith(['18180000'])]
29
public function testCorrectSubuserIsDeletedFromServer(?string $prefix)
30
{
31
[$user, $server] = $this->generateTestAccount();
32
33
/** @var User $differentUser */
34
$differentUser = User::factory()->create();
35
36
$real = Uuid::uuid4()->toString();
37
// Generate a UUID that lines up with a user in the database if it were to be cast to an int.
38
$uuid = ($prefix ?: $differentUser->id) . substr($real, strlen($prefix ?: (string) $differentUser->id));
39
40
/** @var User $subuser */
41
$subuser = User::factory()->create(['uuid' => $uuid]);
42
43
Subuser::query()->forceCreate([
44
'user_id' => $subuser->id,
45
'server_id' => $server->id,
46
'permissions' => [Permission::ACTION_WEBSOCKET_CONNECT],
47
]);
48
49
$this->mock(DaemonRevocationRepository::class, function (MockInterface $mock) use ($subuser, $server) {
50
$mock->expects('setNode')
51
->with(\Mockery::on(fn ($value) => $value->is($server->node)))
52
->andReturnSelf();
53
54
$mock->expects('deauthorize')
55
->with($subuser->uuid, [$server->uuid])
56
->andReturnUndefined();
57
});
58
59
$this->withoutExceptionHandling()
60
->actingAs($user)
61
->deleteJson($this->link($server) . "/users/$subuser->uuid")->assertNoContent();
62
}
63
}
64
65