Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/tests/Integration/Api/Client/Server/Database/DatabaseAuthorizationTest.php
7461 views
1
<?php
2
3
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Database;
4
5
use Pterodactyl\Models\Subuser;
6
use Pterodactyl\Models\Database;
7
use Pterodactyl\Models\DatabaseHost;
8
use Pterodactyl\Contracts\Extensions\HashidsInterface;
9
use Pterodactyl\Services\Databases\DatabasePasswordService;
10
use Pterodactyl\Services\Databases\DatabaseManagementService;
11
use Pterodactyl\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
12
13
class DatabaseAuthorizationTest extends ClientApiIntegrationTestCase
14
{
15
#[\PHPUnit\Framework\Attributes\DataProvider('methodDataProvider')]
16
public function testAccessToAServersDatabasesIsRestrictedProperly(string $method, string $endpoint)
17
{
18
// The API $user is the owner of $server1.
19
[$user, $server1] = $this->generateTestAccount();
20
// Will be a subuser of $server2.
21
$server2 = $this->createServerModel();
22
// And as no access to $server3.
23
$server3 = $this->createServerModel();
24
25
$host = DatabaseHost::factory()->create([]);
26
27
// Set the API $user as a subuser of server 2, but with no permissions
28
// to do anything with the databases for that server.
29
Subuser::factory()->create(['server_id' => $server2->id, 'user_id' => $user->id]);
30
31
$database1 = Database::factory()->create(['server_id' => $server1->id, 'database_host_id' => $host->id]);
32
$database2 = Database::factory()->create(['server_id' => $server2->id, 'database_host_id' => $host->id]);
33
$database3 = Database::factory()->create(['server_id' => $server3->id, 'database_host_id' => $host->id]);
34
35
$this
36
->mock($method === 'POST' ? DatabasePasswordService::class : DatabaseManagementService::class)
37
->expects($method === 'POST' ? 'handle' : 'delete')
38
->andReturn($method === 'POST' ? 'foo' : null);
39
40
$hashids = $this->app->make(HashidsInterface::class);
41
// This is the only valid call for this test, accessing the database for the same
42
// server that the API user is the owner of.
43
$this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $hashids->encode($database1->id) . $endpoint))
44
->assertStatus($method === 'DELETE' ? 204 : 200);
45
46
// This request fails because the database is valid for that server but the user
47
// making the request is not authorized to perform that action.
48
$this->actingAs($user)->json($method, $this->link($server2, '/databases/' . $hashids->encode($database2->id) . $endpoint))->assertForbidden();
49
50
// Both of these should report a 404 error due to the database being linked to
51
// servers that are not the same as the server in the request, or are assigned
52
// to a server for which the user making the request has no access to.
53
$this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $hashids->encode($database2->id) . $endpoint))->assertNotFound();
54
$this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $hashids->encode($database3->id) . $endpoint))->assertNotFound();
55
$this->actingAs($user)->json($method, $this->link($server2, '/databases/' . $hashids->encode($database3->id) . $endpoint))->assertNotFound();
56
$this->actingAs($user)->json($method, $this->link($server3, '/databases/' . $hashids->encode($database3->id) . $endpoint))->assertNotFound();
57
}
58
59
public static function methodDataProvider(): array
60
{
61
return [
62
['POST', '/rotate-password'],
63
['DELETE', ''],
64
];
65
}
66
}
67
68