Path: blob/1.0-develop/tests/Integration/Api/Application/Users/UserControllerTest.php
7461 views
<?php12namespace Pterodactyl\Tests\Integration\Api\Application\Users;34use Pterodactyl\Models\User;5use Illuminate\Http\Response;6use Pterodactyl\Services\Acl\Api\AdminAcl;7use Pterodactyl\Transformers\Api\Application\UserTransformer;8use Pterodactyl\Transformers\Api\Application\ServerTransformer;9use Pterodactyl\Tests\Integration\Api\Application\ApplicationApiIntegrationTestCase;1011class UserControllerTest extends ApplicationApiIntegrationTestCase12{13/**14* Test the response when requesting all users on the panel.15*/16public function testGetUsers()17{18$user = User::factory()->create();1920$response = $this->getJson('/api/application/users?per_page=60');21$response->assertStatus(Response::HTTP_OK);22$response->assertJsonCount(2, 'data');23$response->assertJsonStructure([24'object',25'data' => [26['object', 'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at']],27['object', 'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at']],28],29'meta' => ['pagination' => ['total', 'count', 'per_page', 'current_page', 'total_pages']],30]);3132$response33->assertJson([34'object' => 'list',35'data' => [[], []],36'meta' => [37'pagination' => [38'total' => 2,39'count' => 2,40'per_page' => 60,41'current_page' => 1,42'total_pages' => 1,43],44],45])46->assertJsonFragment([47'object' => 'user',48'attributes' => [49'id' => $this->getApiUser()->id,50'external_id' => $this->getApiUser()->external_id,51'uuid' => $this->getApiUser()->uuid,52'username' => $this->getApiUser()->username,53'email' => $this->getApiUser()->email,54'first_name' => $this->getApiUser()->name_first,55'last_name' => $this->getApiUser()->name_last,56'language' => $this->getApiUser()->language,57'root_admin' => $this->getApiUser()->root_admin,58'2fa' => (bool) $this->getApiUser()->totp_enabled,59'created_at' => $this->formatTimestamp($this->getApiUser()->created_at),60'updated_at' => $this->formatTimestamp($this->getApiUser()->updated_at),61],62])63->assertJsonFragment([64'object' => 'user',65'attributes' => [66'id' => $user->id,67'external_id' => $user->external_id,68'uuid' => $user->uuid,69'username' => $user->username,70'email' => $user->email,71'first_name' => $user->name_first,72'last_name' => $user->name_last,73'language' => $user->language,74'root_admin' => (bool) $user->root_admin,75'2fa' => (bool) $user->totp_enabled,76'created_at' => $this->formatTimestamp($user->created_at),77'updated_at' => $this->formatTimestamp($user->updated_at),78],79]);80}8182/**83* Test getting a single user.84*/85public function testGetSingleUser()86{87$user = User::factory()->create();8889$response = $this->getJson('/api/application/users/' . $user->id);90$response->assertStatus(Response::HTTP_OK);91$response->assertJsonCount(2);92$response->assertJsonStructure([93'object',94'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at'],95]);9697$response->assertJson([98'object' => 'user',99'attributes' => [100'id' => $user->id,101'external_id' => $user->external_id,102'uuid' => $user->uuid,103'username' => $user->username,104'email' => $user->email,105'first_name' => $user->name_first,106'last_name' => $user->name_last,107'language' => $user->language,108'root_admin' => (bool) $user->root_admin,109'2fa' => (bool) $user->totp_enabled,110'created_at' => $this->formatTimestamp($user->created_at),111'updated_at' => $this->formatTimestamp($user->updated_at),112],113]);114}115116/**117* Test that the correct relationships can be loaded.118*/119public function testRelationshipsCanBeLoaded()120{121$user = User::factory()->create();122$server = $this->createServerModel(['user_id' => $user->id]);123124$response = $this->getJson('/api/application/users/' . $user->id . '?include=servers');125$response->assertStatus(Response::HTTP_OK);126$response->assertJsonCount(2);127$response->assertJsonStructure([128'object',129'attributes' => [130'id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at',131'relationships' => ['servers' => ['object', 'data' => [['object', 'attributes' => []]]]],132],133]);134135$response->assertJsonFragment([136'object' => 'list',137'data' => [138[139'object' => 'server',140'attributes' => $this->getTransformer(ServerTransformer::class)->transform($server),141],142],143]);144}145146/**147* Test that attempting to load a relationship that the key does not have permission148* for returns a null object.149*/150public function testKeyWithoutPermissionCannotLoadRelationship()151{152$this->createNewDefaultApiKey($this->getApiUser(), ['r_servers' => 0]);153154$user = User::factory()->create();155$this->createServerModel(['user_id' => $user->id]);156157$response = $this->getJson('/api/application/users/' . $user->id . '?include=servers');158$response->assertStatus(Response::HTTP_OK);159$response->assertJsonCount(2)->assertJsonCount(1, 'attributes.relationships');160$response->assertJsonStructure([161'attributes' => [162'relationships' => [163'servers' => ['object', 'attributes'],164],165],166]);167168// Just assert that we see the expected relationship IDs in the response.169$response->assertJson([170'attributes' => [171'relationships' => [172'servers' => [173'object' => 'null_resource',174'attributes' => null,175],176],177],178]);179}180181/**182* Test that an invalid external ID returns a 404 error.183*/184public function testGetMissingUser()185{186$response = $this->getJson('/api/application/users/nil');187$this->assertNotFoundJson($response);188}189190/**191* Test that an authentication error occurs if a key does not have permission192* to access a resource.193*/194public function testErrorReturnedIfNoPermission()195{196$user = User::factory()->create();197$this->createNewDefaultApiKey($this->getApiUser(), ['r_users' => 0]);198199$response = $this->getJson('/api/application/users/' . $user->id);200$this->assertAccessDeniedJson($response);201}202203/**204* Test that a user can be created.205*/206public function testCreateUser()207{208$response = $this->postJson('/api/application/users', [209'username' => 'testuser',210'email' => '[email protected]',211'first_name' => 'Test',212'last_name' => 'User',213]);214215$response->assertStatus(Response::HTTP_CREATED);216$response->assertJsonCount(3);217$response->assertJsonStructure([218'object',219'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at'],220'meta' => ['resource'],221]);222223$this->assertDatabaseHas('users', ['username' => 'testuser', 'email' => '[email protected]']);224225$user = User::where('username', 'testuser')->first();226$response->assertJson([227'object' => 'user',228'attributes' => $this->getTransformer(UserTransformer::class)->transform($user),229'meta' => [230'resource' => route('api.application.users.view', $user->id),231],232], true);233}234235/**236* Test that a user can be updated.237*/238public function testUpdateUser()239{240$user = User::factory()->create();241242$response = $this->patchJson('/api/application/users/' . $user->id, [243'username' => 'new.test.name',244'email' => '[email protected]',245'first_name' => $user->name_first,246'last_name' => $user->name_last,247]);248$response->assertStatus(Response::HTTP_OK);249$response->assertJsonCount(2);250$response->assertJsonStructure([251'object',252'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at'],253]);254255$this->assertDatabaseHas('users', ['username' => 'new.test.name', 'email' => '[email protected]']);256$user = $user->fresh();257258$response->assertJson([259'object' => 'user',260'attributes' => $this->getTransformer(UserTransformer::class)->transform($user),261]);262}263264/**265* Test that a user can be deleted from the database.266*/267public function testDeleteUser()268{269$user = User::factory()->create();270$this->assertDatabaseHas('users', ['id' => $user->id]);271272$response = $this->delete('/api/application/users/' . $user->id);273$response->assertStatus(Response::HTTP_NO_CONTENT);274275$this->assertDatabaseMissing('users', ['id' => $user->id]);276}277278/**279* Test that an API key without write permissions cannot create, update, or280* delete a user model.281*/282#[\PHPUnit\Framework\Attributes\DataProvider('userWriteEndpointsDataProvider')]283public function testApiKeyWithoutWritePermissions(string $method, string $url)284{285$this->createNewDefaultApiKey($this->getApiUser(), ['r_users' => AdminAcl::READ]);286287if (str_contains($url, '{id}')) {288$user = User::factory()->create();289$url = str_replace('{id}', $user->id, $url);290}291292$response = $this->$method($url);293$this->assertAccessDeniedJson($response);294}295296/**297* Endpoints that should return a 403 error when the key does not have write298* permissions for user management.299*/300public static function userWriteEndpointsDataProvider(): array301{302return [303['postJson', '/api/application/users'],304['patchJson', '/api/application/users/{id}'],305['delete', '/api/application/users/{id}'],306];307}308}309310311