Skip to content

Commit f31a6d3

Browse files
committed
Fix parameter bindings for client API routes; closes pterodactyl#2359
1 parent 1db7e4d commit f31a6d3

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

app/Http/Middleware/Api/Client/SubstituteClientApiBindings.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ public function handle($request, Closure $next)
4949
return Database::query()->where('id', $id)->firstOrFail();
5050
});
5151

52-
$this->router->model('backup', Backup::class, function ($value) {
52+
$this->router->bind('backup', function ($value) {
5353
return Backup::query()->where('uuid', $value)->firstOrFail();
5454
});
5555

56-
$this->router->model('user', User::class, function ($value) {
56+
$this->router->bind('user', function ($value) {
5757
return User::query()->where('uuid', $value)->firstOrFail();
5858
});
5959

tests/Integration/Api/Client/Server/Subuser/CreateServerSubuserTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Schedule;
3+
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Subuser;
44

55
use Illuminate\Support\Str;
66
use Pterodactyl\Models\User;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Subuser;
4+
5+
use Ramsey\Uuid\Uuid;
6+
use Pterodactyl\Models\User;
7+
use Pterodactyl\Models\Subuser;
8+
use Pterodactyl\Models\Permission;
9+
use Pterodactyl\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
10+
11+
class DeleteSubuserTest extends ClientApiIntegrationTestCase
12+
{
13+
/**
14+
* Guards against PHP's exciting behavior where a string can be cast to an int and only
15+
* the first numeric digits are returned. This causes UUIDs to be returned as an int when
16+
* looking up users, thus returning the wrong subusers (or no subuser at all).
17+
*
18+
* For example, 12aaaaaa-bbbb-cccc-ddddeeeeffff would be cast to "12" if you tried to cast
19+
* it to an integer. Then, in the deep API middlewares you would end up trying to load a user
20+
* with an ID of 12, which may or may not exist and be wrongly assigned to the model object.
21+
*
22+
* @see https://github.com/pterodactyl/panel/issues/2359
23+
*/
24+
public function testCorrectSubuserIsDeletedFromServer()
25+
{
26+
[$user, $server] = $this->generateTestAccount();
27+
28+
/** @var \Pterodactyl\Models\User $differentUser */
29+
$differentUser = factory(User::class)->create();
30+
31+
// Generate a UUID that lines up with a user in the database if it were to be cast to an int.
32+
$uuid = $differentUser->id . str_repeat('a', strlen((string)$differentUser->id)) . substr(Uuid::uuid4()->toString(), 8);
33+
34+
/** @var \Pterodactyl\Models\User $subuser */
35+
$subuser = factory(User::class)->create(['uuid' => $uuid]);
36+
37+
Subuser::query()->forceCreate([
38+
'user_id' => $subuser->id,
39+
'server_id' => $server->id,
40+
'permissions' => [ Permission::ACTION_WEBSOCKET_CONNECT ],
41+
]);
42+
43+
$this->actingAs($user)->deleteJson($this->link($server) . "/users/{$subuser->uuid}")->assertNoContent();
44+
45+
// Try the same test, but this time with a UUID that if cast to an int (shouldn't) line up with
46+
// anything in the database.
47+
$uuid = '18180000' . substr(Uuid::uuid4()->toString(), 8);
48+
/** @var \Pterodactyl\Models\User $subuser */
49+
$subuser = factory(User::class)->create(['uuid' => $uuid]);
50+
51+
Subuser::query()->forceCreate([
52+
'user_id' => $subuser->id,
53+
'server_id' => $server->id,
54+
'permissions' => [ Permission::ACTION_WEBSOCKET_CONNECT ],
55+
]);
56+
57+
$this->actingAs($user)->deleteJson($this->link($server) . "/users/{$subuser->uuid}")->assertNoContent();
58+
}
59+
}

0 commit comments

Comments
 (0)