mirror of
https://github.com/pterodactyl/panel.git
synced 2026-06-14 21:03:32 -05:00
This expands upon previous work done to better disconnect users from SFTP when different events occur within Pterodactyl. This new logic also accounts for password changes and their account being deleted entirely from the system. These events now trigger background jobs that will reach out to every node they are associated with to ensure they're disconnected if currently connected.
152 lines
5.0 KiB
PHP
152 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Subuser;
|
|
|
|
use Pterodactyl\Models\User;
|
|
use Pterodactyl\Models\Subuser;
|
|
use Pterodactyl\Models\Permission;
|
|
use Illuminate\Support\Facades\Bus;
|
|
use Pterodactyl\Jobs\RevokeSftpAccessJob;
|
|
use Pterodactyl\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
|
|
|
|
class UpdateSubuserTest extends ClientApiIntegrationTestCase
|
|
{
|
|
/**
|
|
* Test that the correct permissions are applied to the account when making updates
|
|
* to a subusers permissions.
|
|
*/
|
|
public function testCorrectPermissionsAreRequiredForUpdating()
|
|
{
|
|
Bus::fake([RevokeSftpAccessJob::class]);
|
|
|
|
[$user, $server] = $this->generateTestAccount(['user.read']);
|
|
|
|
$subuser = Subuser::factory()
|
|
->for(User::factory()->create())
|
|
->for($server)
|
|
->create([
|
|
'permissions' => ['control.start'],
|
|
]);
|
|
|
|
$this->postJson(
|
|
$endpoint = "/api/client/servers/$server->uuid/users/{$subuser->user->uuid}",
|
|
$data = [
|
|
'permissions' => [
|
|
'control.start',
|
|
'control.stop',
|
|
],
|
|
]
|
|
)
|
|
->assertUnauthorized();
|
|
|
|
$this->actingAs($subuser->user)->postJson($endpoint, $data)->assertForbidden();
|
|
$this->actingAs($user)->postJson($endpoint, $data)->assertForbidden();
|
|
|
|
$server->subusers()->where('user_id', $user->id)->update([
|
|
'permissions' => [
|
|
Permission::ACTION_USER_UPDATE,
|
|
Permission::ACTION_CONTROL_START,
|
|
Permission::ACTION_CONTROL_STOP,
|
|
],
|
|
]);
|
|
|
|
$this->postJson($endpoint, $data)->assertOk();
|
|
|
|
Bus::assertDispatchedTimes(function (RevokeSftpAccessJob $job) use ($server, $subuser) {
|
|
return $job->user === $subuser->user->uuid && $job->target->is($server);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Tests that permissions for the account are updated and any extraneous values
|
|
* we don't know about are removed.
|
|
*/
|
|
public function testPermissionsAreSavedToAccount()
|
|
{
|
|
Bus::fake([RevokeSftpAccessJob::class]);
|
|
|
|
[$user, $server] = $this->generateTestAccount();
|
|
|
|
/** @var Subuser $subuser */
|
|
$subuser = Subuser::factory()
|
|
->for(User::factory()->create())
|
|
->for($server)
|
|
->create([
|
|
'permissions' => ['control.restart', 'websocket.connect', 'foo.bar'],
|
|
]);
|
|
|
|
$this->actingAs($user)
|
|
->postJson("/api/client/servers/$server->uuid/users/{$subuser->user->uuid}", [
|
|
'permissions' => [
|
|
'control.start',
|
|
'control.stop',
|
|
'control.stop',
|
|
'foo.bar',
|
|
'power.fake',
|
|
],
|
|
])
|
|
->assertOk();
|
|
|
|
$subuser->refresh();
|
|
$this->assertEqualsCanonicalizing(
|
|
['control.start', 'control.stop', 'websocket.connect'],
|
|
$subuser->permissions
|
|
);
|
|
|
|
Bus::assertDispatchedTimes(function (RevokeSftpAccessJob $job) use ($server, $subuser) {
|
|
return $job->user === $subuser->user->uuid && $job->target->is($server);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Ensure a subuser cannot assign permissions to an account that they do not have
|
|
* themselves.
|
|
*/
|
|
public function testUserCannotAssignPermissionsTheyDoNotHave()
|
|
{
|
|
Bus::fake([RevokeSftpAccessJob::class]);
|
|
|
|
[$user, $server] = $this->generateTestAccount([Permission::ACTION_USER_READ, Permission::ACTION_USER_UPDATE]);
|
|
|
|
$subuser = Subuser::factory()
|
|
->for(User::factory()->create())
|
|
->for($server)
|
|
->create(['permissions' => ['foo.bar']]);
|
|
|
|
$this->actingAs($user)
|
|
->postJson("/api/client/servers/$server->uuid/users/{$subuser->user->uuid}", [
|
|
'permissions' => [Permission::ACTION_USER_READ, Permission::ACTION_CONTROL_CONSOLE],
|
|
])
|
|
->assertForbidden();
|
|
|
|
$this->assertEqualsCanonicalizing(['foo.bar'], $subuser->refresh()->permissions);
|
|
|
|
Bus::assertNothingDispatched();
|
|
}
|
|
|
|
/**
|
|
* Test that a user cannot update thyself.
|
|
*/
|
|
public function testUserCannotUpdateSelf()
|
|
{
|
|
[$user, $server] = $this->generateTestAccount([Permission::ACTION_USER_READ, Permission::ACTION_USER_UPDATE]);
|
|
|
|
$this->actingAs($user)
|
|
->postJson("/api/client/servers/$server->uuid/users/$user->uuid", [])
|
|
->assertForbidden();
|
|
}
|
|
|
|
/**
|
|
* Test that an error is returned if you attempt to update a subuser on a different account.
|
|
*/
|
|
public function testCannotUpdateSubuserForDifferentServer()
|
|
{
|
|
[$user, $server] = $this->generateTestAccount();
|
|
[$user2] = $this->generateTestAccount(['foo.bar']);
|
|
|
|
$this->actingAs($user)
|
|
->postJson("/api/client/servers/$server->uuid/users/$user2->uuid", [])
|
|
->assertNotFound();
|
|
}
|
|
}
|