mirror of
				https://github.com/pelican-dev/panel.git
				synced 2025-11-04 05:06:51 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			290 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			290 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace App\Tests\Integration\Api\Client;
 | 
						|
 | 
						|
use App\Models\Objects\Endpoint;
 | 
						|
use App\Models\User;
 | 
						|
use App\Models\Server;
 | 
						|
use App\Models\Subuser;
 | 
						|
use App\Models\Permission;
 | 
						|
 | 
						|
class ClientControllerTest extends ClientApiIntegrationTestCase
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * Test that only the servers a logged-in user is assigned to are returned by the
 | 
						|
     * API endpoint. Obviously there are cases such as being an administrator or being
 | 
						|
     * a subuser, but for this test we just want to test a basic scenario and pretend
 | 
						|
     * subusers do not exist at all.
 | 
						|
     */
 | 
						|
    public function testOnlyLoggedInUsersServersAreReturned(): void
 | 
						|
    {
 | 
						|
        /** @var \App\Models\User[] $users */
 | 
						|
        $users = User::factory()->times(3)->create();
 | 
						|
 | 
						|
        /** @var \App\Models\Server[] $servers */
 | 
						|
        $servers = [
 | 
						|
            $this->createServerModel(['user_id' => $users[0]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[1]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[2]->id]),
 | 
						|
        ];
 | 
						|
 | 
						|
        $response = $this->actingAs($users[0])->getJson('/api/client');
 | 
						|
 | 
						|
        $response->assertOk();
 | 
						|
        $response->assertJsonPath('object', 'list');
 | 
						|
        $response->assertJsonPath('data.0.object', Server::RESOURCE_NAME);
 | 
						|
        $response->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuid_short);
 | 
						|
        $response->assertJsonPath('data.0.attributes.server_owner', true);
 | 
						|
        $response->assertJsonPath('meta.pagination.total', 1);
 | 
						|
        $response->assertJsonPath('meta.pagination.per_page', 50);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that using ?filter[*]=name|uuid returns any server matching that name or UUID
 | 
						|
     * with the search filters.
 | 
						|
     */
 | 
						|
    public function testServersAreFilteredUsingNameAndUuidInformation(): void
 | 
						|
    {
 | 
						|
        /** @var \App\Models\User[] $users */
 | 
						|
        $users = User::factory()->times(2)->create();
 | 
						|
        $users[0]->update(['root_admin' => true]);
 | 
						|
 | 
						|
        /** @var \App\Models\Server[] $servers */
 | 
						|
        $servers = [
 | 
						|
            $this->createServerModel(['user_id' => $users[0]->id, 'name' => 'Julia']),
 | 
						|
            $this->createServerModel(['user_id' => $users[1]->id, 'uuid_short' => '12121212', 'name' => 'Janice']),
 | 
						|
            $this->createServerModel(['user_id' => $users[1]->id, 'uuid' => '88788878-12356789', 'external_id' => 'ext123', 'name' => 'Julia']),
 | 
						|
            $this->createServerModel(['user_id' => $users[1]->id, 'uuid' => '88788878-abcdefgh', 'name' => 'Jennifer']),
 | 
						|
        ];
 | 
						|
 | 
						|
        $this->actingAs($users[1])->getJson('/api/client?filter[*]=Julia')
 | 
						|
            ->assertOk()
 | 
						|
            ->assertJsonCount(1, 'data')
 | 
						|
            ->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuid_short);
 | 
						|
 | 
						|
        $this->actingAs($users[1])->getJson('/api/client?filter[*]=ext123')
 | 
						|
            ->assertOk()
 | 
						|
            ->assertJsonCount(1, 'data')
 | 
						|
            ->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuid_short);
 | 
						|
 | 
						|
        $this->actingAs($users[1])->getJson('/api/client?filter[*]=ext123')
 | 
						|
            ->assertOk()
 | 
						|
            ->assertJsonCount(1, 'data')
 | 
						|
            ->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuid_short);
 | 
						|
 | 
						|
        $this->actingAs($users[1])->getJson('/api/client?filter[*]=12121212')
 | 
						|
            ->assertOk()
 | 
						|
            ->assertJsonCount(1, 'data')
 | 
						|
            ->assertJsonPath('data.0.attributes.identifier', $servers[1]->uuid_short);
 | 
						|
 | 
						|
        $this->actingAs($users[1])->getJson('/api/client?filter[*]=88788878')
 | 
						|
            ->assertOk()
 | 
						|
            ->assertJsonCount(2, 'data')
 | 
						|
            ->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuid_short)
 | 
						|
            ->assertJsonPath('data.1.attributes.identifier', $servers[3]->uuid_short);
 | 
						|
 | 
						|
        $this->actingAs($users[1])->getJson('/api/client?filter[*]=88788878-abcd')
 | 
						|
            ->assertOk()
 | 
						|
            ->assertJsonCount(1, 'data')
 | 
						|
            ->assertJsonPath('data.0.attributes.identifier', $servers[3]->uuid_short);
 | 
						|
 | 
						|
        $this->actingAs($users[0])->getJson('/api/client?filter[*]=Julia&type=admin-all')
 | 
						|
            ->assertOk()
 | 
						|
            ->assertJsonCount(2, 'data')
 | 
						|
            ->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuid_short)
 | 
						|
            ->assertJsonPath('data.1.attributes.identifier', $servers[2]->uuid_short);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that servers where the user is a subuser are returned by default in the API call.
 | 
						|
     */
 | 
						|
    public function testServersUserIsASubuserOfAreReturned(): void
 | 
						|
    {
 | 
						|
        /** @var \App\Models\User[] $users */
 | 
						|
        $users = User::factory()->times(3)->create();
 | 
						|
        $servers = [
 | 
						|
            $this->createServerModel(['user_id' => $users[0]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[1]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[2]->id]),
 | 
						|
        ];
 | 
						|
 | 
						|
        // Set user 0 as a subuser of server 1. Thus, we should get two servers
 | 
						|
        // back in the response when making the API call as user 0.
 | 
						|
        Subuser::query()->create([
 | 
						|
            'user_id' => $users[0]->id,
 | 
						|
            'server_id' => $servers[1]->id,
 | 
						|
            'permissions' => [Permission::ACTION_WEBSOCKET_CONNECT],
 | 
						|
        ]);
 | 
						|
 | 
						|
        $response = $this->actingAs($users[0])->getJson('/api/client');
 | 
						|
 | 
						|
        $response->assertOk();
 | 
						|
        $response->assertJsonCount(2, 'data');
 | 
						|
        $response->assertJsonPath('data.0.attributes.server_owner', true);
 | 
						|
        $response->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuid_short);
 | 
						|
        $response->assertJsonPath('data.1.attributes.server_owner', false);
 | 
						|
        $response->assertJsonPath('data.1.attributes.identifier', $servers[1]->uuid_short);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns only servers that the user owns, not servers they are a subuser of.
 | 
						|
     */
 | 
						|
    public function testFilterOnlyOwnerServers(): void
 | 
						|
    {
 | 
						|
        /** @var \App\Models\User[] $users */
 | 
						|
        $users = User::factory()->times(3)->create();
 | 
						|
        $servers = [
 | 
						|
            $this->createServerModel(['user_id' => $users[0]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[1]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[2]->id]),
 | 
						|
        ];
 | 
						|
 | 
						|
        // Set user 0 as a subuser of server 1. Thus, we should get two servers
 | 
						|
        // back in the response when making the API call as user 0.
 | 
						|
        Subuser::query()->create([
 | 
						|
            'user_id' => $users[0]->id,
 | 
						|
            'server_id' => $servers[1]->id,
 | 
						|
            'permissions' => [Permission::ACTION_WEBSOCKET_CONNECT],
 | 
						|
        ]);
 | 
						|
 | 
						|
        $response = $this->actingAs($users[0])->getJson('/api/client?type=owner');
 | 
						|
 | 
						|
        $response->assertOk();
 | 
						|
        $response->assertJsonCount(1, 'data');
 | 
						|
        $response->assertJsonPath('data.0.attributes.server_owner', true);
 | 
						|
        $response->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuid_short);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests that the permissions from the Panel are returned correctly.
 | 
						|
     */
 | 
						|
    public function testPermissionsAreReturned(): void
 | 
						|
    {
 | 
						|
        /** @var \App\Models\User $user */
 | 
						|
        $user = User::factory()->create();
 | 
						|
 | 
						|
        $this->actingAs($user)
 | 
						|
            ->getJson('/api/client/permissions')
 | 
						|
            ->assertOk()
 | 
						|
            ->assertJson([
 | 
						|
                'object' => 'system_permissions',
 | 
						|
                'attributes' => [
 | 
						|
                    'permissions' => Permission::permissions()->toArray(),
 | 
						|
                ],
 | 
						|
            ]);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that only servers a user can access because they are an administrator are returned. This
 | 
						|
     * will always exclude any servers they can see because they're the owner or a subuser of the server.
 | 
						|
     */
 | 
						|
    public function testOnlyAdminLevelServersAreReturned(): void
 | 
						|
    {
 | 
						|
        /** @var \App\Models\User[] $users */
 | 
						|
        $users = User::factory()->times(4)->create();
 | 
						|
        $users[0]->update(['root_admin' => true]);
 | 
						|
 | 
						|
        $servers = [
 | 
						|
            $this->createServerModel(['user_id' => $users[0]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[1]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[2]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[3]->id]),
 | 
						|
        ];
 | 
						|
 | 
						|
        Subuser::query()->create([
 | 
						|
            'user_id' => $users[0]->id,
 | 
						|
            'server_id' => $servers[1]->id,
 | 
						|
            'permissions' => [Permission::ACTION_WEBSOCKET_CONNECT],
 | 
						|
        ]);
 | 
						|
 | 
						|
        // Only servers 2 & 3 (0 indexed) should be returned by the API at this point. The user making
 | 
						|
        // the request is the owner of server 0, and a subuser of server 1, so they should be excluded.
 | 
						|
        $response = $this->actingAs($users[0])->getJson('/api/client?type=admin');
 | 
						|
 | 
						|
        $response->assertOk();
 | 
						|
        $response->assertJsonCount(2, 'data');
 | 
						|
 | 
						|
        $response->assertJsonPath('data.0.attributes.server_owner', false);
 | 
						|
        $response->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuid_short);
 | 
						|
        $response->assertJsonPath('data.1.attributes.server_owner', false);
 | 
						|
        $response->assertJsonPath('data.1.attributes.identifier', $servers[3]->uuid_short);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that all servers a user can access as an admin are returned if using ?filter=admin-all.
 | 
						|
     */
 | 
						|
    public function testAllServersAreReturnedToAdmin(): void
 | 
						|
    {
 | 
						|
        /** @var \App\Models\User[] $users */
 | 
						|
        $users = User::factory()->times(4)->create();
 | 
						|
        $users[0]->update(['root_admin' => true]);
 | 
						|
 | 
						|
        $servers = [
 | 
						|
            $this->createServerModel(['user_id' => $users[0]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[1]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[2]->id]),
 | 
						|
            $this->createServerModel(['user_id' => $users[3]->id]),
 | 
						|
        ];
 | 
						|
 | 
						|
        Subuser::query()->create([
 | 
						|
            'user_id' => $users[0]->id,
 | 
						|
            'server_id' => $servers[1]->id,
 | 
						|
            'permissions' => [Permission::ACTION_WEBSOCKET_CONNECT],
 | 
						|
        ]);
 | 
						|
 | 
						|
        // All servers should be returned.
 | 
						|
        $response = $this->actingAs($users[0])->getJson('/api/client?type=admin-all');
 | 
						|
 | 
						|
        $response->assertOk();
 | 
						|
        $response->assertJsonCount(4, 'data');
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that no servers get returned if the user requests all admin level servers by using
 | 
						|
     * ?type=admin or ?type=admin-all in the request.
 | 
						|
     *
 | 
						|
     * @dataProvider filterTypeDataProvider
 | 
						|
     */
 | 
						|
    public function testNoServersAreReturnedIfAdminFilterIsPassedByRegularUser(string $type): void
 | 
						|
    {
 | 
						|
        /** @var \App\Models\User[] $users */
 | 
						|
        $users = User::factory()->times(3)->create();
 | 
						|
 | 
						|
        $this->createServerModel(['user_id' => $users[0]->id]);
 | 
						|
        $this->createServerModel(['user_id' => $users[1]->id]);
 | 
						|
        $this->createServerModel(['user_id' => $users[2]->id]);
 | 
						|
 | 
						|
        $response = $this->actingAs($users[0])->getJson('/api/client?type=' . $type);
 | 
						|
 | 
						|
        $response->assertOk();
 | 
						|
        $response->assertJsonCount(0, 'data');
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that a subuser without the allocation.read permission cannot see any ports
 | 
						|
     */
 | 
						|
    public function testNoPortsAreReturnedToSubuser(): void
 | 
						|
    {
 | 
						|
        /** @var \App\Models\Server $server */
 | 
						|
        [$user, $server] = $this->generateTestAccount([Permission::ACTION_WEBSOCKET_CONNECT]);
 | 
						|
        $server->ports->add(new Endpoint(1234));
 | 
						|
        $server->ports->add(new Endpoint(2345, '1.2.3.4'));
 | 
						|
        $server->ports->add(new Endpoint(3456));
 | 
						|
        $server->save();
 | 
						|
 | 
						|
        $server->refresh();
 | 
						|
        $response = $this->actingAs($user)->getJson('/api/client');
 | 
						|
 | 
						|
        $response->assertOk();
 | 
						|
        $response->assertJsonCount(1, 'data');
 | 
						|
        $response->assertJsonPath('data.0.attributes.server_owner', false);
 | 
						|
        $response->assertJsonPath('data.0.attributes.uuid', $server->uuid);
 | 
						|
        $response->assertJsonCount(0, 'data.0.attributes.ports');
 | 
						|
    }
 | 
						|
 | 
						|
    public static function filterTypeDataProvider(): array
 | 
						|
    {
 | 
						|
        return [['admin'], ['admin-all']];
 | 
						|
    }
 | 
						|
}
 |