Implement Panel changes to support internal SFTP subsystem on Daemon (#703)
This commit is contained in:
parent
57db949a9c
commit
058e490ec4
23 changed files with 484 additions and 247 deletions
|
@ -63,11 +63,6 @@ class ServerCreationService
|
|||
*/
|
||||
protected $userRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\UsernameGenerationService
|
||||
*/
|
||||
protected $usernameService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\VariableValidatorService
|
||||
*/
|
||||
|
@ -84,7 +79,6 @@ class ServerCreationService
|
|||
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
|
||||
* @param \Pterodactyl\Contracts\Repository\ServerVariableRepositoryInterface $serverVariableRepository
|
||||
* @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $userRepository
|
||||
* @param \Pterodactyl\Services\Servers\UsernameGenerationService $usernameService
|
||||
* @param \Pterodactyl\Services\Servers\VariableValidatorService $validatorService
|
||||
*/
|
||||
public function __construct(
|
||||
|
@ -96,7 +90,6 @@ class ServerCreationService
|
|||
ServerRepositoryInterface $repository,
|
||||
ServerVariableRepositoryInterface $serverVariableRepository,
|
||||
UserRepositoryInterface $userRepository,
|
||||
UsernameGenerationService $usernameService,
|
||||
VariableValidatorService $validatorService
|
||||
) {
|
||||
$this->allocationRepository = $allocationRepository;
|
||||
|
@ -107,7 +100,6 @@ class ServerCreationService
|
|||
$this->repository = $repository;
|
||||
$this->serverVariableRepository = $serverVariableRepository;
|
||||
$this->userRepository = $userRepository;
|
||||
$this->usernameService = $usernameService;
|
||||
$this->validatorService = $validatorService;
|
||||
}
|
||||
|
||||
|
@ -151,8 +143,6 @@ class ServerCreationService
|
|||
'startup' => $data['startup'],
|
||||
'daemonSecret' => str_random(NodeCreationService::DAEMON_SECRET_LENGTH),
|
||||
'image' => $data['docker_image'],
|
||||
'username' => $this->usernameService->generate($data['name'], $uniqueShort),
|
||||
'sftp_password' => null,
|
||||
]);
|
||||
|
||||
// Process allocations and assign them to the server in the database.
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Services\Servers;
|
||||
|
||||
class UsernameGenerationService
|
||||
{
|
||||
/**
|
||||
* Generate a unique username to be used for SFTP connections and identification
|
||||
* of the server docker container on the host system.
|
||||
*
|
||||
* @param string $name
|
||||
* @param null $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function generate($name, $identifier = null)
|
||||
{
|
||||
if (is_null($identifier) || ! ctype_alnum($identifier)) {
|
||||
$unique = str_random(8);
|
||||
} else {
|
||||
if (strlen($identifier) < 8) {
|
||||
$unique = $identifier . str_random((8 - strlen($identifier)));
|
||||
} else {
|
||||
$unique = substr($identifier, 0, 8);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter the Server Name
|
||||
$name = trim(preg_replace('/[^A-Za-z0-9]+/', '', $name), '_');
|
||||
$name = (strlen($name) < 1) ? str_random(6) : $name;
|
||||
|
||||
return strtolower(substr($name, 0, 6) . '_' . $unique);
|
||||
}
|
||||
}
|
90
app/Services/Sftp/AuthenticateUsingPasswordService.php
Normal file
90
app/Services/Sftp/AuthenticateUsingPasswordService.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Services\Sftp;
|
||||
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
||||
use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService;
|
||||
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
||||
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||
|
||||
class AuthenticateUsingPasswordService
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService
|
||||
*/
|
||||
private $keyProviderService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
|
||||
*/
|
||||
private $userRepository;
|
||||
|
||||
/**
|
||||
* AuthenticateUsingPasswordService constructor.
|
||||
*
|
||||
* @param \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService $keyProviderService
|
||||
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
|
||||
* @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $userRepository
|
||||
*/
|
||||
public function __construct(
|
||||
DaemonKeyProviderService $keyProviderService,
|
||||
ServerRepositoryInterface $repository,
|
||||
UserRepositoryInterface $userRepository
|
||||
) {
|
||||
$this->keyProviderService = $keyProviderService;
|
||||
$this->repository = $repository;
|
||||
$this->userRepository = $userRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to authenticate a provded username and password and determine if they
|
||||
* have permission to access a given server. This function does not account for
|
||||
* subusers currently. Only administrators and server owners can login to access
|
||||
* their files at this time.
|
||||
*
|
||||
* Server must exist on the node that the API call is being made from in order for a
|
||||
* valid response to be provided.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string|null $server
|
||||
* @param int $node
|
||||
* @return array
|
||||
*
|
||||
* @throws \Illuminate\Auth\AuthenticationException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function handle(string $username, string $password, int $node, string $server = null): array
|
||||
{
|
||||
if (is_null($server)) {
|
||||
throw new RecordNotFoundException;
|
||||
}
|
||||
|
||||
try {
|
||||
$user = $this->userRepository->withColumns(['id', 'root_admin', 'password'])->findFirstWhere([['username', '=', $username]]);
|
||||
|
||||
if (! password_verify($password, $user->password)) {
|
||||
throw new AuthenticationException;
|
||||
}
|
||||
} catch (RecordNotFoundException $exception) {
|
||||
throw new AuthenticationException;
|
||||
}
|
||||
|
||||
$server = $this->repository->withColumns(['id', 'node_id', 'owner_id', 'uuid'])->getByUuid($server);
|
||||
if ($server->node_id !== $node || (! $user->root_admin && $server->owner_id !== $user->id)) {
|
||||
throw new RecordNotFoundException;
|
||||
}
|
||||
|
||||
return [
|
||||
'server' => $server->uuid,
|
||||
'token' => $this->keyProviderService->handle($server->id, $user->id),
|
||||
];
|
||||
}
|
||||
}
|
Reference in a new issue