Merge branch 'master' into develop
This commit is contained in:
commit
81143e231a
41 changed files with 303 additions and 190 deletions
|
@ -102,7 +102,10 @@ class BulkPowerActionCommand extends Command
|
|||
$bar->clear();
|
||||
|
||||
try {
|
||||
$this->powerRepository->setServer($server)->sendSignal($action);
|
||||
$this->powerRepository
|
||||
->setNode($server->node)
|
||||
->setServer($server)
|
||||
->sendSignal($action);
|
||||
} catch (RequestException $exception) {
|
||||
$this->output->error(trans('command/messages.server.power.action_failed', [
|
||||
'name' => $server->name,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Exception;
|
||||
use PDOException;
|
||||
use Illuminate\View\View;
|
||||
use Pterodactyl\Models\DatabaseHost;
|
||||
|
@ -118,17 +119,22 @@ class DatabaseController extends Controller
|
|||
* @param \Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function create(DatabaseHostFormRequest $request): RedirectResponse
|
||||
{
|
||||
try {
|
||||
$host = $this->creationService->handle($request->normalize());
|
||||
} catch (PDOException $ex) {
|
||||
$this->alert->danger($ex->getMessage())->flash();
|
||||
} catch (Exception $exception) {
|
||||
if ($exception instanceof PDOException || $exception->getPrevious() instanceof PDOException) {
|
||||
$this->alert->danger(
|
||||
sprintf('There was an error while trying to connect to the host or while executing a query: "%s"', $exception->getMessage())
|
||||
)->flash();
|
||||
|
||||
return redirect()->route('admin.databases');
|
||||
redirect()->route('admin.databases')->withInput($request->validated());
|
||||
} else {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
$this->alert->success('Successfully created a new database host on the system.')->flash();
|
||||
|
@ -143,8 +149,7 @@ class DatabaseController extends Controller
|
|||
* @param \Pterodactyl\Models\DatabaseHost $host
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function update(DatabaseHostFormRequest $request, DatabaseHost $host): RedirectResponse
|
||||
{
|
||||
|
@ -153,9 +158,17 @@ class DatabaseController extends Controller
|
|||
try {
|
||||
$this->updateService->handle($host->id, $request->normalize());
|
||||
$this->alert->success('Database host was updated successfully.')->flash();
|
||||
} catch (PDOException $ex) {
|
||||
$this->alert->danger($ex->getMessage())->flash();
|
||||
$redirect->withInput($request->normalize());
|
||||
} catch (Exception $exception) {
|
||||
// Catch any SQL related exceptions and display them back to the user, otherwise just
|
||||
// throw the exception like normal and move on with it.
|
||||
if ($exception instanceof PDOException || $exception->getPrevious() instanceof PDOException) {
|
||||
$this->alert->danger(
|
||||
sprintf('There was an error while trying to connect to the host or while executing a query: "%s"', $exception->getMessage())
|
||||
)->flash();
|
||||
$redirect->withInput($request->normalize());
|
||||
} else {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
|
|
|
@ -516,7 +516,7 @@ class ServersController extends Controller
|
|||
$this->buildModificationService->handle($server, $request->only([
|
||||
'allocation_id', 'add_allocations', 'remove_allocations',
|
||||
'memory', 'swap', 'io', 'cpu', 'disk',
|
||||
'database_limit', 'allocation_limit',
|
||||
'database_limit', 'allocation_limit', 'oom_disabled',
|
||||
]));
|
||||
$this->alert->success(trans('admin/server.alerts.build_updated'))->flash();
|
||||
|
||||
|
@ -589,8 +589,7 @@ class ServersController extends Controller
|
|||
* @param int $server
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function resetDatabasePassword(Request $request, $server)
|
||||
{
|
||||
|
@ -599,7 +598,7 @@ class ServersController extends Controller
|
|||
['id', '=', $request->input('database')],
|
||||
]);
|
||||
|
||||
$this->databasePasswordService->handle($database, str_random(24));
|
||||
$this->databasePasswordService->handle($database);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
|
|
|
@ -87,12 +87,11 @@ class DatabaseController extends ApplicationApiController
|
|||
* @param \Pterodactyl\Http\Requests\Api\Application\Servers\Databases\ServerDatabaseWriteRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function resetPassword(ServerDatabaseWriteRequest $request): Response
|
||||
{
|
||||
$this->databasePasswordService->handle($request->getModel(Database::class), str_random(24));
|
||||
$this->databasePasswordService->handle($request->getModel(Database::class));
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
|
|
|
@ -35,9 +35,28 @@ class ClientController extends ClientApiController
|
|||
*/
|
||||
public function index(GetServersRequest $request): array
|
||||
{
|
||||
$servers = $this->repository
|
||||
// Check for the filter parameter on the request.
|
||||
switch ($request->input('filter')) {
|
||||
case 'all':
|
||||
$filter = User::FILTER_LEVEL_ALL;
|
||||
break;
|
||||
case 'admin':
|
||||
$filter = User::FILTER_LEVEL_ADMIN;
|
||||
break;
|
||||
case 'owner':
|
||||
$filter = User::FILTER_LEVEL_OWNER;
|
||||
break;
|
||||
case 'subuser-of':
|
||||
default:
|
||||
$filter = User::FILTER_LEVEL_SUBUSER;
|
||||
break;
|
||||
}
|
||||
|
||||
$servers = $this->repository->
|
||||
->setSearchTerm($request->input('query'))
|
||||
->filterUserAccessServers($request->user(), User::FILTER_LEVEL_ALL);
|
||||
->filterUserAccessServers(
|
||||
$request->user(), $filter, config('pterodactyl.paginate.frontend.servers')
|
||||
);
|
||||
|
||||
return $this->fractal->collection($servers)
|
||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
||||
|
|
|
@ -40,7 +40,7 @@ class StoreAllocationRequest extends ApplicationApiRequest
|
|||
return [
|
||||
'allocation_ip' => $data['ip'],
|
||||
'allocation_ports' => $data['ports'],
|
||||
'allocation_alias' => $data['alias'],
|
||||
'allocation_alias' => $data['alias'] ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ class StoreServerRequest extends ApplicationApiRequest
|
|||
'startup' => $rules['startup'],
|
||||
'environment' => 'present|array',
|
||||
'skip_scripts' => 'sometimes|boolean',
|
||||
'oom_disabled' => 'sometimes|boolean',
|
||||
|
||||
// Resource limitations
|
||||
'limits' => 'required|array',
|
||||
|
|
|
@ -18,6 +18,7 @@ class UpdateServerBuildConfigurationRequest extends ServerWriteRequest
|
|||
|
||||
return [
|
||||
'allocation' => $rules['allocation_id'],
|
||||
'oom_disabled' => $rules['oom_disabled'],
|
||||
|
||||
'limits' => 'sometimes|array',
|
||||
'limits.memory' => $this->requiredToOptional('memory', $rules['memory'], true),
|
||||
|
|
|
@ -28,6 +28,16 @@ class Server extends Model implements CleansAttributes, ValidableContract
|
|||
*/
|
||||
protected $table = 'servers';
|
||||
|
||||
/**
|
||||
* Default values when creating the model. We want to switch to disabling OOM killer
|
||||
* on server instances unless the user specifies otherwise in the request.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = [
|
||||
'oom_disabled' => true,
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be mutated to dates.
|
||||
*
|
||||
|
@ -53,6 +63,7 @@ class Server extends Model implements CleansAttributes, ValidableContract
|
|||
'swap' => 'required',
|
||||
'io' => 'required',
|
||||
'cpu' => 'required',
|
||||
'oom_disabled' => 'sometimes',
|
||||
'disk' => 'required',
|
||||
'nest_id' => 'required',
|
||||
'egg_id' => 'required',
|
||||
|
@ -79,6 +90,7 @@ class Server extends Model implements CleansAttributes, ValidableContract
|
|||
'swap' => 'numeric|min:-1',
|
||||
'io' => 'numeric|between:10,1000',
|
||||
'cpu' => 'numeric|min:0',
|
||||
'oom_disabled' => 'boolean',
|
||||
'disk' => 'numeric|min:0',
|
||||
'allocation_id' => 'bail|unique:servers|exists:allocations,id',
|
||||
'nest_id' => 'exists:nests,id',
|
||||
|
@ -107,7 +119,7 @@ class Server extends Model implements CleansAttributes, ValidableContract
|
|||
'disk' => 'integer',
|
||||
'io' => 'integer',
|
||||
'cpu' => 'integer',
|
||||
'oom_disabled' => 'integer',
|
||||
'oom_disabled' => 'boolean',
|
||||
'allocation_id' => 'integer',
|
||||
'nest_id' => 'integer',
|
||||
'egg_id' => 'integer',
|
||||
|
@ -164,11 +176,11 @@ class Server extends Model implements CleansAttributes, ValidableContract
|
|||
/**
|
||||
* Gets the subusers associated with a server.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
||||
*/
|
||||
public function subusers()
|
||||
{
|
||||
return $this->hasMany(Subuser::class);
|
||||
return $this->hasManyThrough(User::class, Subuser::class, 'server_id', 'id', 'id', 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -153,7 +153,7 @@ class DatabaseRepository extends EloquentRepository implements DatabaseRepositor
|
|||
public function assignUserToDatabase(string $database, string $username, string $remote): bool
|
||||
{
|
||||
return $this->run(sprintf(
|
||||
'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, EXECUTE ON `%s`.* TO `%s`@`%s`',
|
||||
'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, LOCK TABLES, EXECUTE ON `%s`.* TO `%s`@`%s`',
|
||||
$database,
|
||||
$username,
|
||||
$remote
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
namespace Pterodactyl\Services\Databases;
|
||||
|
||||
use Webmozart\Assert\Assert;
|
||||
use Exception;
|
||||
use Pterodactyl\Models\Database;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Contracts\Encryption\Encrypter;
|
||||
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
||||
|
@ -55,35 +56,39 @@ class DatabasePasswordService
|
|||
* Updates a password for a given database.
|
||||
*
|
||||
* @param \Pterodactyl\Models\Database|int $database
|
||||
* @param string $password
|
||||
* @return bool
|
||||
* @return string
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function handle($database, string $password): bool
|
||||
public function handle(Database $database): string
|
||||
{
|
||||
if (! $database instanceof Database) {
|
||||
Assert::integerish($database);
|
||||
$password = str_random(24);
|
||||
// Given a random string of characters, randomly loop through the characters and replace some
|
||||
// with special characters to avoid issues with MySQL password requirements on some servers.
|
||||
try {
|
||||
for ($i = 0; $i < random_int(2, 6); $i++) {
|
||||
$character = ['!', '@', '=', '.', '+', '^'][random_int(0, 5)];
|
||||
|
||||
$database = $this->repository->find($database);
|
||||
$password = substr_replace($password, $character, random_int(0, 23), 1);
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
// Just log the error and hope for the best at this point.
|
||||
Log::error($exception);
|
||||
}
|
||||
|
||||
$this->dynamic->set('dynamic', $database->database_host_id);
|
||||
$this->connection->beginTransaction();
|
||||
$this->connection->transaction(function () use ($database, $password) {
|
||||
$this->dynamic->set('dynamic', $database->database_host_id);
|
||||
|
||||
$updated = $this->repository->withoutFreshModel()->update($database->id, [
|
||||
'password' => $this->encrypter->encrypt($password),
|
||||
]);
|
||||
$this->repository->withoutFreshModel()->update($database->id, [
|
||||
'password' => $this->encrypter->encrypt($password),
|
||||
]);
|
||||
|
||||
$this->repository->dropUser($database->username, $database->remote);
|
||||
$this->repository->createUser($database->username, $database->remote, $password);
|
||||
$this->repository->assignUserToDatabase($database->database, $database->username, $database->remote);
|
||||
$this->repository->flush();
|
||||
$this->repository->dropUser($database->username, $database->remote);
|
||||
$this->repository->createUser($database->username, $database->remote, $password);
|
||||
$this->repository->assignUserToDatabase($database->database, $database->username, $database->remote);
|
||||
$this->repository->flush();
|
||||
});
|
||||
|
||||
unset($password);
|
||||
$this->connection->commit();
|
||||
|
||||
return $updated;
|
||||
return $password;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,28 +65,26 @@ class HostCreationService
|
|||
* @param array $data
|
||||
* @return \Pterodactyl\Models\DatabaseHost
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function handle(array $data): DatabaseHost
|
||||
{
|
||||
$this->connection->beginTransaction();
|
||||
return $this->connection->transaction(function () use ($data) {
|
||||
$host = $this->repository->create([
|
||||
'password' => $this->encrypter->encrypt(array_get($data, 'password')),
|
||||
'name' => array_get($data, 'name'),
|
||||
'host' => array_get($data, 'host'),
|
||||
'port' => array_get($data, 'port'),
|
||||
'username' => array_get($data, 'username'),
|
||||
'max_databases' => null,
|
||||
'node_id' => array_get($data, 'node_id'),
|
||||
]);
|
||||
|
||||
$host = $this->repository->create([
|
||||
'password' => $this->encrypter->encrypt(array_get($data, 'password')),
|
||||
'name' => array_get($data, 'name'),
|
||||
'host' => array_get($data, 'host'),
|
||||
'port' => array_get($data, 'port'),
|
||||
'username' => array_get($data, 'username'),
|
||||
'max_databases' => null,
|
||||
'node_id' => array_get($data, 'node_id'),
|
||||
]);
|
||||
// Confirm access using the provided credentials before saving data.
|
||||
$this->dynamic->set('dynamic', $host);
|
||||
$this->databaseManager->connection('dynamic')->select('SELECT 1 FROM dual');
|
||||
|
||||
// Confirm access using the provided credentials before saving data.
|
||||
$this->dynamic->set('dynamic', $host);
|
||||
$this->databaseManager->connection('dynamic')->select('SELECT 1 FROM dual');
|
||||
$this->connection->commit();
|
||||
|
||||
return $host;
|
||||
return $host;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,10 +71,9 @@ class HostUpdateService
|
|||
*
|
||||
* @param int $hostId
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
* @return \Pterodactyl\Models\DatabaseHost
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function handle(int $hostId, array $data): DatabaseHost
|
||||
{
|
||||
|
@ -84,13 +83,12 @@ class HostUpdateService
|
|||
unset($data['password']);
|
||||
}
|
||||
|
||||
$this->connection->beginTransaction();
|
||||
$host = $this->repository->update($hostId, $data);
|
||||
return $this->connection->transaction(function () use ($data, $hostId) {
|
||||
$host = $this->repository->update($hostId, $data);
|
||||
$this->dynamic->set('dynamic', $host);
|
||||
$this->databaseManager->connection('dynamic')->select('SELECT 1 FROM dual');
|
||||
|
||||
$this->dynamic->set('dynamic', $host);
|
||||
$this->databaseManager->connection('dynamic')->select('SELECT 1 FROM dual');
|
||||
$this->connection->commit();
|
||||
|
||||
return $host;
|
||||
return $host;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ class BuildModificationService
|
|||
}
|
||||
|
||||
$server = $this->repository->withFreshModel()->update($server->id, [
|
||||
'oom_disabled' => array_get($data, 'oom_disabled'),
|
||||
'memory' => array_get($data, 'memory'),
|
||||
'swap' => array_get($data, 'swap'),
|
||||
'io' => array_get($data, 'io'),
|
||||
|
@ -97,6 +98,7 @@ class BuildModificationService
|
|||
|
||||
$allocations = $this->allocationRepository->findWhere([['server_id', '=', $server->id]]);
|
||||
|
||||
$build['oom_disabled'] = $server->oom_disabled;
|
||||
$build['memory'] = (int) $server->memory;
|
||||
$build['swap'] = (int) $server->swap;
|
||||
$build['io'] = (int) $server->io;
|
||||
|
|
|
@ -70,6 +70,7 @@ class ServerConfigurationStructureService
|
|||
return $item->pluck('port');
|
||||
})->toArray(),
|
||||
'env' => $this->environment->handle($server),
|
||||
'oom_disabled' => $server->oom_disabled,
|
||||
'memory' => (int) $server->memory,
|
||||
'swap' => (int) $server->swap,
|
||||
'io' => (int) $server->io,
|
||||
|
|
|
@ -227,7 +227,7 @@ class ServerCreationService
|
|||
'disk' => array_get($data, 'disk'),
|
||||
'io' => array_get($data, 'io'),
|
||||
'cpu' => array_get($data, 'cpu'),
|
||||
'oom_disabled' => false,
|
||||
'oom_disabled' => array_get($data, 'oom_disabled', true),
|
||||
'allocation_id' => array_get($data, 'allocation_id'),
|
||||
'nest_id' => array_get($data, 'nest_id'),
|
||||
'egg_id' => array_get($data, 'egg_id'),
|
||||
|
|
|
@ -71,7 +71,7 @@ class TwoFactorSetupService
|
|||
'totp_secret' => $this->encrypter->encrypt($secret),
|
||||
]);
|
||||
|
||||
$company = $this->config->get('app.name');
|
||||
$company = preg_replace('/\s/', '', $this->config->get('app.name'));
|
||||
|
||||
return sprintf(
|
||||
'otpauth://totp/%1$s:%2$s?secret=%3$s&issuer=%1$s',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue