2017-10-25 04:35:25 +00:00
|
|
|
<?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;
|
2018-02-17 22:10:44 +00:00
|
|
|
use Pterodactyl\Contracts\Repository\SubuserRepositoryInterface;
|
2017-10-25 04:35:25 +00:00
|
|
|
|
|
|
|
class AuthenticateUsingPasswordServiceTest extends TestCase
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService|\Mockery\Mock
|
|
|
|
*/
|
|
|
|
private $keyProviderService;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface|\Mockery\Mock
|
|
|
|
*/
|
|
|
|
private $repository;
|
2018-02-17 22:10:44 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var \Pterodactyl\Contracts\Repository\SubuserRepositoryInterface|\Mockery\Mock
|
|
|
|
*/
|
|
|
|
private $subuserRepository;
|
2017-10-25 04:35:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @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);
|
2018-02-17 22:10:44 +00:00
|
|
|
$this->subuserRepository = m::mock(SubuserRepositoryInterface::class);
|
2017-10-25 04:35:25 +00:00
|
|
|
$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]);
|
|
|
|
|
2018-01-05 04:49:50 +00:00
|
|
|
$this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
|
2017-10-25 04:35:25 +00:00
|
|
|
$this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
|
|
|
|
|
2018-01-31 04:40:21 +00:00
|
|
|
$this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid', 'installed', 'suspended'])->once()->andReturnSelf();
|
2017-10-25 04:35:25 +00:00
|
|
|
$this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server);
|
|
|
|
|
2017-11-05 18:38:39 +00:00
|
|
|
$this->keyProviderService->shouldReceive('handle')->with($server, $user)->once()->andReturn('server_token');
|
2017-10-25 04:35:25 +00:00
|
|
|
|
|
|
|
$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]);
|
|
|
|
|
2018-01-05 04:49:50 +00:00
|
|
|
$this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
|
2017-10-25 04:35:25 +00:00
|
|
|
$this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
|
|
|
|
|
2018-01-31 04:40:21 +00:00
|
|
|
$this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid', 'installed', 'suspended'])->once()->andReturnSelf();
|
2017-10-25 04:35:25 +00:00
|
|
|
$this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server);
|
|
|
|
|
2017-11-05 18:38:39 +00:00
|
|
|
$this->keyProviderService->shouldReceive('handle')->with($server, $user)->once()->andReturn('server_token');
|
2017-10-25 04:35:25 +00:00
|
|
|
|
|
|
|
$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.
|
|
|
|
*
|
2018-01-31 04:40:21 +00:00
|
|
|
* @expectedException \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
2017-10-25 04:35:25 +00:00
|
|
|
*/
|
|
|
|
public function testExceptionIsThrownIfUserDetailsAreIncorrect()
|
|
|
|
{
|
|
|
|
$user = factory(User::class)->make();
|
|
|
|
|
2018-01-05 04:49:50 +00:00
|
|
|
$this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
|
2017-10-25 04:35:25 +00:00
|
|
|
$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.
|
|
|
|
*
|
2018-01-31 04:40:21 +00:00
|
|
|
* @expectedException \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
2017-10-25 04:35:25 +00:00
|
|
|
*/
|
|
|
|
public function testExceptionIsThrownIfNoUserAccountIsFound()
|
|
|
|
{
|
2018-01-05 04:49:50 +00:00
|
|
|
$this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
|
2017-10-25 04:35:25 +00:00
|
|
|
$this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', 'something']])->once()->andThrow(new RecordNotFoundException);
|
|
|
|
|
|
|
|
$this->getService()->handle('something', 'password', 1, '1234');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-02-17 22:10:44 +00:00
|
|
|
* 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.
|
2017-10-25 04:35:25 +00:00
|
|
|
*
|
|
|
|
* @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]);
|
|
|
|
|
2018-01-05 04:49:50 +00:00
|
|
|
$this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
|
2017-10-25 04:35:25 +00:00
|
|
|
$this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
|
|
|
|
|
2018-01-31 04:40:21 +00:00
|
|
|
$this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid', 'installed', 'suspended'])->once()->andReturnSelf();
|
2017-10-25 04:35:25 +00:00
|
|
|
$this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server);
|
|
|
|
|
2018-02-17 22:10:44 +00:00
|
|
|
$this->subuserRepository->shouldReceive('getWithPermissionsUsingUserAndServer')->with($user->id, $server->id)->once()->andThrow(new RecordNotFoundException);
|
|
|
|
|
2017-10-25 04:35:25 +00:00
|
|
|
$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]);
|
|
|
|
|
2018-01-05 04:49:50 +00:00
|
|
|
$this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf();
|
2017-10-25 04:35:25 +00:00
|
|
|
$this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user);
|
|
|
|
|
2018-01-31 04:40:21 +00:00
|
|
|
$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();
|
2017-10-25 04:35:25 +00:00
|
|
|
$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
|
|
|
|
{
|
2018-02-17 22:10:44 +00:00
|
|
|
return new AuthenticateUsingPasswordService($this->keyProviderService, $this->repository, $this->subuserRepository, $this->userRepository);
|
2017-10-25 04:35:25 +00:00
|
|
|
}
|
|
|
|
}
|