Path: blob/1.0-develop/tests/Integration/Api/Client/Server/Schedule/ScheduleAuthorizationTest.php
7461 views
<?php12namespace Pterodactyl\Tests\Integration\Api\Client\Server\Schedule;34use Pterodactyl\Models\Subuser;5use Pterodactyl\Models\Schedule;6use Pterodactyl\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;78class ScheduleAuthorizationTest extends ClientApiIntegrationTestCase9{10/**11* Tests that a subuser with access to two servers cannot improperly access a resource12* on Server A when providing a URL that points to Server B. This prevents a regression13* in the code where controllers didn't properly validate that a resource was assigned14* to the server that was also present in the URL.15*16* The comments within the test code itself are better at explaining exactly what is17* being tested and protected against.18*/19#[\PHPUnit\Framework\Attributes\DataProvider('methodDataProvider')]20public function testAccessToAServersSchedulesIsRestrictedProperly(string $method, string $endpoint)21{22// The API $user is the owner of $server1.23[$user, $server1] = $this->generateTestAccount();24// Will be a subuser of $server2.25$server2 = $this->createServerModel();26// And as no access to $server3.27$server3 = $this->createServerModel();2829// Set the API $user as a subuser of server 2, but with no permissions30// to do anything with the schedules for that server.31Subuser::factory()->create(['server_id' => $server2->id, 'user_id' => $user->id]);3233$schedule1 = Schedule::factory()->create(['server_id' => $server1->id]);34$schedule2 = Schedule::factory()->create(['server_id' => $server2->id]);35$schedule3 = Schedule::factory()->create(['server_id' => $server3->id]);3637// This is the only valid call for this test, accessing the schedule for the same38// server that the API user is the owner of.39$response = $this->actingAs($user)->json($method, $this->link($server1, '/schedules/' . $schedule1->id . $endpoint));40$this->assertTrue($response->status() <= 204 || $response->status() === 400 || $response->status() === 422);4142// This request fails because the schedule is valid for that server but the user43// making the request is not authorized to perform that action.44$this->actingAs($user)->json($method, $this->link($server2, '/schedules/' . $schedule2->id . $endpoint))->assertForbidden();4546// Both of these should report a 404 error due to the schedules being linked to47// servers that are not the same as the server in the request, or are assigned48// to a server for which the user making the request has no access to.49$this->actingAs($user)->json($method, $this->link($server1, '/schedules/' . $schedule2->id . $endpoint))->assertNotFound();50$this->actingAs($user)->json($method, $this->link($server1, '/schedules/' . $schedule3->id . $endpoint))->assertNotFound();51$this->actingAs($user)->json($method, $this->link($server2, '/schedules/' . $schedule3->id . $endpoint))->assertNotFound();52$this->actingAs($user)->json($method, $this->link($server3, '/schedules/' . $schedule3->id . $endpoint))->assertNotFound();53}5455public static function methodDataProvider(): array56{57return [58['GET', ''],59['POST', ''],60['DELETE', ''],61['POST', '/execute'],62['POST', '/tasks'],63];64}65}666768