mirror of
				https://github.com/pelican-dev/panel.git
				synced 2025-11-04 11:26:52 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			229 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			229 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace Tests\Unit\Services\Sftp;
 | 
						|
 | 
						|
use Mockery as m;
 | 
						|
use Tests\TestCase;
 | 
						|
use Pterodactyl\Models\User;
 | 
						|
use Pterodactyl\Models\Server;
 | 
						|
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
 | 
						|
use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService;
 | 
						|
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
 | 
						|
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
 | 
						|
use Pterodactyl\Services\Sftp\AuthenticateUsingPasswordService;
 | 
						|
use Pterodactyl\Contracts\Repository\SubuserRepositoryInterface;
 | 
						|
 | 
						|
class AuthenticateUsingPasswordServiceTest extends TestCase
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService|\Mockery\Mock
 | 
						|
     */
 | 
						|
    private $keyProviderService;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface|\Mockery\Mock
 | 
						|
     */
 | 
						|
    private $repository;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var \Pterodactyl\Contracts\Repository\SubuserRepositoryInterface|\Mockery\Mock
 | 
						|
     */
 | 
						|
    private $subuserRepository;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface|\Mockery\Mock
 | 
						|
     */
 | 
						|
    private $userRepository;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Setup tests.
 | 
						|
     */
 | 
						|
    public function setUp()
 | 
						|
    {
 | 
						|
        parent::setUp();
 | 
						|
 | 
						|
        $this->keyProviderService = m::mock(DaemonKeyProviderService::class);
 | 
						|
        $this->repository = m::mock(ServerRepositoryInterface::class);
 | 
						|
        $this->subuserRepository = m::mock(SubuserRepositoryInterface::class);
 | 
						|
        $this->userRepository = m::mock(UserRepositoryInterface::class);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that an account can be authenticated.
 | 
						|
     */
 | 
						|
    public function testNonAdminAccountIsAuthenticated()
 | 
						|
    {
 | 
						|
        $user = factory(User::class)->make(['root_admin' => 0]);
 | 
						|
        $server = factory(Server::class)->make(['node_id' => 1, 'owner_id' => $user->id]);
 | 
						|
 | 
						|
        $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
 | 
						|
        $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
 | 
						|
 | 
						|
        $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid', 'installed', 'suspended'])->once()->andReturnSelf();
 | 
						|
        $this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server);
 | 
						|
 | 
						|
        $this->keyProviderService->shouldReceive('handle')->with($server, $user)->once()->andReturn('server_token');
 | 
						|
 | 
						|
        $response = $this->getService()->handle($user->username, 'password', 1, $server->uuidShort);
 | 
						|
        $this->assertNotEmpty($response);
 | 
						|
        $this->assertArrayHasKey('server', $response);
 | 
						|
        $this->assertArrayHasKey('token', $response);
 | 
						|
        $this->assertSame($server->uuid, $response['server']);
 | 
						|
        $this->assertSame('server_token', $response['token']);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that an administrative user can access servers that they are not
 | 
						|
     * set as the owner of.
 | 
						|
     */
 | 
						|
    public function testAdminAccountIsAuthenticated()
 | 
						|
    {
 | 
						|
        $user = factory(User::class)->make(['root_admin' => 1]);
 | 
						|
        $server = factory(Server::class)->make(['node_id' => 1, 'owner_id' => $user->id + 1]);
 | 
						|
 | 
						|
        $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
 | 
						|
        $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
 | 
						|
 | 
						|
        $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid', 'installed', 'suspended'])->once()->andReturnSelf();
 | 
						|
        $this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server);
 | 
						|
 | 
						|
        $this->keyProviderService->shouldReceive('handle')->with($server, $user)->once()->andReturn('server_token');
 | 
						|
 | 
						|
        $response = $this->getService()->handle($user->username, 'password', 1, $server->uuidShort);
 | 
						|
        $this->assertNotEmpty($response);
 | 
						|
        $this->assertArrayHasKey('server', $response);
 | 
						|
        $this->assertArrayHasKey('token', $response);
 | 
						|
        $this->assertSame($server->uuid, $response['server']);
 | 
						|
        $this->assertSame('server_token', $response['token']);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test exception gets thrown if no server is passed into the function.
 | 
						|
     *
 | 
						|
     * @expectedException \Pterodactyl\Exceptions\Repository\RecordNotFoundException
 | 
						|
     */
 | 
						|
    public function testExceptionIsThrownIfNoServerIsProvided()
 | 
						|
    {
 | 
						|
        $this->getService()->handle('username', 'password', 1);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that an exception is thrown if the user account exists but the wrong
 | 
						|
     * credentials are passed.
 | 
						|
     *
 | 
						|
     * @expectedException \Pterodactyl\Exceptions\Repository\RecordNotFoundException
 | 
						|
     */
 | 
						|
    public function testExceptionIsThrownIfUserDetailsAreIncorrect()
 | 
						|
    {
 | 
						|
        $user = factory(User::class)->make();
 | 
						|
 | 
						|
        $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
 | 
						|
        $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
 | 
						|
 | 
						|
        $this->getService()->handle($user->username, 'wrongpassword', 1, '1234');
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that an exception is thrown if no user account is found.
 | 
						|
     *
 | 
						|
     * @expectedException \Pterodactyl\Exceptions\Repository\RecordNotFoundException
 | 
						|
     */
 | 
						|
    public function testExceptionIsThrownIfNoUserAccountIsFound()
 | 
						|
    {
 | 
						|
        $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
 | 
						|
        $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', 'something']])->once()->andThrow(new RecordNotFoundException);
 | 
						|
 | 
						|
        $this->getService()->handle('something', 'password', 1, '1234');
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that an exception is thrown if the user is not the owner of the server,
 | 
						|
     * is not a sub user and is not an administrator.
 | 
						|
     *
 | 
						|
     * @expectedException \Pterodactyl\Exceptions\Repository\RecordNotFoundException
 | 
						|
     */
 | 
						|
    public function testExceptionIsThrownIfUserDoesNotOwnServer()
 | 
						|
    {
 | 
						|
        $user = factory(User::class)->make(['root_admin' => 0]);
 | 
						|
        $server = factory(Server::class)->make(['node_id' => 1, 'owner_id' => $user->id + 1]);
 | 
						|
 | 
						|
        $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
 | 
						|
        $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
 | 
						|
 | 
						|
        $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid', 'installed', 'suspended'])->once()->andReturnSelf();
 | 
						|
        $this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server);
 | 
						|
 | 
						|
        $this->subuserRepository->shouldReceive('getWithPermissionsUsingUserAndServer')->with($user->id, $server->id)->once()->andThrow(new RecordNotFoundException);
 | 
						|
 | 
						|
        $this->getService()->handle($user->username, 'password', 1, $server->uuidShort);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that an exception is thrown if the requested server does not belong to
 | 
						|
     * the node that the request is made from.
 | 
						|
     *
 | 
						|
     * @expectedException \Pterodactyl\Exceptions\Repository\RecordNotFoundException
 | 
						|
     */
 | 
						|
    public function testExceptionIsThrownIfServerDoesNotExistOnCurrentNode()
 | 
						|
    {
 | 
						|
        $user = factory(User::class)->make(['root_admin' => 0]);
 | 
						|
        $server = factory(Server::class)->make(['node_id' => 2, 'owner_id' => $user->id]);
 | 
						|
 | 
						|
        $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
 | 
						|
        $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
 | 
						|
 | 
						|
        $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid', 'installed', 'suspended'])->once()->andReturnSelf();
 | 
						|
        $this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server);
 | 
						|
 | 
						|
        $this->getService()->handle($user->username, 'password', 1, $server->uuidShort);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that a suspended server throws an exception.
 | 
						|
     *
 | 
						|
     * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
 | 
						|
     */
 | 
						|
    public function testSuspendedServer()
 | 
						|
    {
 | 
						|
        $user = factory(User::class)->make(['root_admin' => 1]);
 | 
						|
        $server = factory(Server::class)->make(['node_id' => 1, 'owner_id' => $user->id + 1, 'suspended' => 1]);
 | 
						|
 | 
						|
        $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
 | 
						|
        $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
 | 
						|
 | 
						|
        $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid', 'installed', 'suspended'])->once()->andReturnSelf();
 | 
						|
        $this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server);
 | 
						|
 | 
						|
        $this->getService()->handle($user->username, 'password', 1, $server->uuidShort);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test that a server that is not yet installed throws an exception.
 | 
						|
     *
 | 
						|
     * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
 | 
						|
     */
 | 
						|
    public function testNotInstalledServer()
 | 
						|
    {
 | 
						|
        $user = factory(User::class)->make(['root_admin' => 1]);
 | 
						|
        $server = factory(Server::class)->make(['node_id' => 1, 'owner_id' => $user->id + 1, 'installed' => 0]);
 | 
						|
 | 
						|
        $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
 | 
						|
        $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
 | 
						|
 | 
						|
        $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid', 'installed', 'suspended'])->once()->andReturnSelf();
 | 
						|
        $this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server);
 | 
						|
 | 
						|
        $this->getService()->handle($user->username, 'password', 1, $server->uuidShort);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return an instance of the service with mocked dependencies.
 | 
						|
     *
 | 
						|
     * @return \Pterodactyl\Services\Sftp\AuthenticateUsingPasswordService
 | 
						|
     */
 | 
						|
    private function getService(): AuthenticateUsingPasswordService
 | 
						|
    {
 | 
						|
        return new AuthenticateUsingPasswordService($this->keyProviderService, $this->repository, $this->subuserRepository, $this->userRepository);
 | 
						|
    }
 | 
						|
}
 |