mirror of
https://github.com/pterodactyl/panel.git
synced 2026-06-15 07:00:48 -05:00
### Description User creation was not properly logged within the action log, neither from sub-user invite or manual user creation. This PR adds the relevant log and includes testing. ### Manual testing scenarios 1. Invite a user within any created server 2. Create a user in the admin 3. Verify both users appear as an action in the action log ### Questions or comments AI was used for secondary testing, QA and code review. No code was written by AI. ### Resolved issues: 1. [x] resolves pterodactyl/panel#5631
209 lines
7.2 KiB
PHP
209 lines
7.2 KiB
PHP
<?php
|
|
|
|
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Subuser;
|
|
|
|
use Illuminate\Support\Str;
|
|
use Pterodactyl\Models\User;
|
|
use Illuminate\Http\Response;
|
|
use Pterodactyl\Models\Subuser;
|
|
use Pterodactyl\Models\Permission;
|
|
use Illuminate\Foundation\Testing\WithFaker;
|
|
use Pterodactyl\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
|
|
|
|
class CreateServerSubuserTest extends ClientApiIntegrationTestCase
|
|
{
|
|
use WithFaker;
|
|
|
|
/**
|
|
* Test that a subuser can be created for a server.
|
|
*/
|
|
#[\PHPUnit\Framework\Attributes\DataProvider('permissionsDataProvider')]
|
|
public function testSubuserCanBeCreated(array $permissions)
|
|
{
|
|
[$user, $server] = $this->generateTestAccount($permissions);
|
|
|
|
$response = $this->actingAs($user)->postJson($this->link($server) . '/users', [
|
|
'email' => $email = $this->faker->email,
|
|
'permissions' => [
|
|
Permission::ACTION_USER_CREATE,
|
|
],
|
|
]);
|
|
|
|
$response->assertOk();
|
|
|
|
/** @var User $subuser */
|
|
$subuser = User::query()->where('email', $email)->firstOrFail();
|
|
|
|
$response->assertJsonPath('object', Subuser::RESOURCE_NAME);
|
|
$response->assertJsonPath('attributes.uuid', $subuser->uuid);
|
|
$response->assertJsonPath('attributes.permissions', [
|
|
Permission::ACTION_USER_CREATE,
|
|
Permission::ACTION_WEBSOCKET_CONNECT,
|
|
]);
|
|
|
|
$expected = $response->json('attributes');
|
|
unset($expected['permissions']);
|
|
|
|
$this->assertJsonTransformedWith($expected, $subuser);
|
|
}
|
|
|
|
/**
|
|
* Test that a newly created user account correctly causes the creation of a user:user.create
|
|
* activity log entry.
|
|
*/
|
|
public function testCreatingSubuserWithNewEmailLogsUserCreation()
|
|
{
|
|
[$user, $server] = $this->generateTestAccount();
|
|
|
|
$response = $this->actingAs($user)->postJson($this->link($server) . '/users', [
|
|
'email' => $email = $this->faker->email,
|
|
'permissions' => [
|
|
Permission::ACTION_USER_CREATE,
|
|
],
|
|
]);
|
|
|
|
$response->assertOk();
|
|
|
|
/** @var User $subuser */
|
|
$subuser = User::query()->where('email', $email)->firstOrFail();
|
|
|
|
$this->assertActivityLogged('user:user.create');
|
|
$this->assertDatabaseHas('activity_logs', [
|
|
'event' => 'user:user.create',
|
|
'actor_type' => $user->getMorphClass(),
|
|
'actor_id' => $user->id,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Tests that an error is returned if a subuser attempts to create a new subuser and assign
|
|
* permissions that their account does not also possess.
|
|
*/
|
|
public function testErrorIsReturnedIfAssigningPermissionsNotAssignedToSelf()
|
|
{
|
|
[$user, $server] = $this->generateTestAccount([
|
|
Permission::ACTION_USER_CREATE,
|
|
Permission::ACTION_USER_READ,
|
|
Permission::ACTION_CONTROL_CONSOLE,
|
|
]);
|
|
|
|
$response = $this->actingAs($user)->postJson($this->link($server) . '/users', [
|
|
'email' => $this->faker->email,
|
|
'permissions' => [
|
|
Permission::ACTION_USER_CREATE,
|
|
Permission::ACTION_USER_UPDATE, // This permission is not assigned to the subuser.
|
|
],
|
|
]);
|
|
|
|
$response->assertForbidden();
|
|
$response->assertJsonPath('errors.0.code', 'HttpForbiddenException');
|
|
$response->assertJsonPath('errors.0.detail', 'Cannot assign permissions to a subuser that your account does not actively possess.');
|
|
}
|
|
|
|
/**
|
|
* Throws some bad data at the API and ensures that a subuser cannot be created.
|
|
*/
|
|
public function testSubuserWithExcessivelyLongEmailCannotBeCreated()
|
|
{
|
|
[$user, $server] = $this->generateTestAccount();
|
|
|
|
/*
|
|
* RFCs limit certain parts of an email to certain character limits.
|
|
*
|
|
* A limit of <= 64 for the local, then <= 63 for each domain label.
|
|
* We will stay below the limit to make sure we're within the 191 column limit for emails.
|
|
*/
|
|
$local = str_repeat(Str::random(10), 6) . '1234';
|
|
$label = str_repeat(Str::random(10), 6) . '1';
|
|
|
|
// Make sure we're within the column limit
|
|
$email = "$local@$label.$label.au";
|
|
|
|
$this->assertSame(64, strlen($local));
|
|
$this->assertSame(61, strlen($label));
|
|
$this->assertSame(191, strlen($email));
|
|
|
|
$response = $this->actingAs($user)->postJson($this->link($server) . '/users', [
|
|
'email' => $email,
|
|
'permissions' => [
|
|
Permission::ACTION_USER_CREATE,
|
|
],
|
|
]);
|
|
|
|
$response->assertOk();
|
|
|
|
// Exceed column limit of 1 >= and <= 191
|
|
$email = "$local@$label.$label.com";
|
|
|
|
$this->assertSame(192, strlen($email));
|
|
|
|
$response = $this->actingAs($user)->postJson($this->link($server) . '/users', [
|
|
'email' => $email,
|
|
'permissions' => [
|
|
Permission::ACTION_USER_CREATE,
|
|
],
|
|
]);
|
|
|
|
$response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
|
|
$response->assertJsonPath('errors.0.detail', 'The email must be between 1 and 191 characters.');
|
|
$response->assertJsonPath('errors.0.meta.source_field', 'email');
|
|
}
|
|
|
|
/**
|
|
* Test that creating a subuser when there is already an account with that email runs
|
|
* as expected and does not create a new account.
|
|
*/
|
|
public function testCreatingSubuserWithSameEmailAsExistingUserWorks()
|
|
{
|
|
[$user, $server] = $this->generateTestAccount();
|
|
|
|
/** @var User $existing */
|
|
$existing = User::factory()->create(['email' => $this->faker->email]);
|
|
|
|
$response = $this->actingAs($user)->postJson($this->link($server) . '/users', [
|
|
'email' => $existing->email,
|
|
'permissions' => [
|
|
Permission::ACTION_USER_CREATE,
|
|
],
|
|
]);
|
|
|
|
$response->assertOk();
|
|
$response->assertJsonPath('object', Subuser::RESOURCE_NAME);
|
|
$response->assertJsonPath('attributes.uuid', $existing->uuid);
|
|
}
|
|
|
|
/**
|
|
* Test that an error is returned if the account associated with an email address is already
|
|
* associated with the server instance.
|
|
*/
|
|
public function testAddingSubuserThatAlreadyIsAssignedReturnsError()
|
|
{
|
|
[$user, $server] = $this->generateTestAccount();
|
|
|
|
$response = $this->actingAs($user)->postJson($this->link($server) . '/users', [
|
|
'email' => $email = $this->faker->email,
|
|
'permissions' => [
|
|
Permission::ACTION_USER_CREATE,
|
|
],
|
|
]);
|
|
|
|
$response->assertOk();
|
|
|
|
$response = $this->actingAs($user)->postJson($this->link($server) . '/users', [
|
|
'email' => $email,
|
|
'permissions' => [
|
|
Permission::ACTION_USER_CREATE,
|
|
],
|
|
]);
|
|
|
|
$response->assertStatus(Response::HTTP_BAD_REQUEST);
|
|
$response->assertJsonPath('errors.0.code', 'ServerSubuserExistsException');
|
|
$response->assertJsonPath('errors.0.detail', 'A user with that email address is already assigned as a subuser for this server.');
|
|
}
|
|
|
|
public static function permissionsDataProvider(): array
|
|
{
|
|
return [[[]], [[Permission::ACTION_USER_CREATE]]];
|
|
}
|
|
}
|